ibm_power_hmc 0.17.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,220 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'time'
4
- require 'uri'
5
-
6
3
  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("=")[1] || filter_type.to_s
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
- ##
78
- # HMC generic K2 non-REST object.
79
- # @abstract
80
- # @attr_reader [REXML::Document] xml The XML document representing this object.
81
- class AbstractNonRest
82
- ATTRS = {}.freeze
83
- attr_reader :xml
84
-
85
- def initialize(xml)
86
- @xml = xml
87
- self.class::ATTRS.each { |varname, xpath| define_attr(varname, xpath) }
88
- end
89
-
90
- ##
91
- # @!method define_attr(varname, xpath)
92
- # Define an instance variable using the text of an XML element as value.
93
- # @param varname [String] The name of the instance variable.
94
- # @param xpath [String] The XPath of the XML element containing the text.
95
- def define_attr(varname, xpath)
96
- value = singleton(xpath)
97
- self.class.__send__(:attr_reader, varname)
98
- self.class.__send__(:define_method, "#{varname}=") do |v|
99
- if v.nil?
100
- xml.elements.delete(xpath)
101
- else
102
- create_element(xpath) if xml.elements[xpath].nil?
103
- xml.elements[xpath].text = v
104
- end
105
- instance_variable_set("@#{varname}", v)
106
- end
107
- instance_variable_set("@#{varname}", value)
108
- end
109
- private :define_attr
110
-
111
- ##
112
- # @!method create_element(xpath)
113
- # Create a new XML element.
114
- # @param xpath [String] The XPath of the XML element to create.
115
- def create_element(xpath)
116
- cur = xml
117
- xpath.split("/").each do |el|
118
- p = cur.elements[el]
119
- if p.nil?
120
- cur = cur.add_element(el)
121
- else
122
- cur = p
123
- end
124
- end
125
- end
126
-
127
- ##
128
- # @!method singleton(xpath, attr = nil)
129
- # Get the text (or the value of a specified attribute) of an XML element.
130
- # @param xpath [String] The XPath of the XML element.
131
- # @param attr [String] The name of the attribute.
132
- # @return [String, nil] The text or attribute value of the XML element or nil.
133
- # @example lpar.singleton("PartitionProcessorConfiguration/*/MaximumVirtualProcessors").to_i
134
- def singleton(xpath, attr = nil)
135
- elem = xml.elements[xpath]
136
- return if elem.nil?
137
-
138
- attr.nil? ? elem.text&.strip : elem.attributes[attr]
139
- end
140
-
141
- def to_s
142
- str = +"#{self.class.name}:\n"
143
- self.class::ATTRS.each do |varname, _|
144
- value = instance_variable_get("@#{varname}")
145
- value = value.nil? ? "null" : "'#{value}'"
146
- str << " #{varname}: #{value}\n"
147
- end
148
- str
149
- end
150
-
151
- def uuid_from_href(href, index = -1)
152
- URI(href).path.split('/')[index]
153
- end
154
-
155
- def uuids_from_links(elem, index = -1)
156
- xml.get_elements("#{elem}/link[@href]").map do |link|
157
- uuid_from_href(link.attributes["href"], index)
158
- end.compact
159
- end
160
-
161
- def collection_of(name, type)
162
- xml.get_elements([name, type].compact.join("/")).map do |elem|
163
- Module.const_get("IbmPowerHmc::#{elem.name}").new(elem)
164
- rescue NameError
165
- nil
166
- end.compact
167
- end
168
- end
169
-
170
- ##
171
- # HMC generic K2 REST object.
172
- # Encapsulate data for a single REST object.
173
- # The XML looks like this:
174
- # <entry>
175
- # <id>uuid</id>
176
- # <published>timestamp</published>
177
- # <link rel="SELF" href="https://..."/>
178
- # <etag:etag>ETag</etag:etag>
179
- # <content type="type">
180
- # <!-- actual content here -->
181
- # </content>
182
- # </entry>
183
- #
184
- # @abstract
185
- # @attr_reader [String] uuid The UUID of the object contained in the entry.
186
- # @attr_reader [Time] published The time at which the entry was published.
187
- # @attr_reader [URI::HTTPS] href The URL of the object itself.
188
- # @attr_reader [String] etag The entity tag of the entry.
189
- # @attr_reader [String] content_type The content type of the object contained in the entry.
190
- class AbstractRest < AbstractNonRest
191
- attr_reader :uuid, :published, :href, :etag, :content_type
192
-
193
- def initialize(entry)
194
- if entry.name != "entry"
195
- # We are inlined.
196
- super(entry)
197
- return
198
- end
199
-
200
- @uuid = entry.elements["id"]&.text
201
- @published = Time.xmlschema(entry.elements["published"]&.text)
202
- link = entry.elements["link[@rel='SELF']"]
203
- @href = URI(link.attributes["href"]) unless link.nil?
204
- @etag = entry.elements["etag:etag"]&.text&.strip
205
- content = entry.elements["content"]
206
- @content_type = content.attributes["type"]
207
- super(content.elements.first)
208
- end
209
-
210
- def to_s
211
- str = super
212
- str << " uuid: '#{uuid}'\n" if defined?(@uuid)
213
- str << " published: '#{published}'\n" if defined?(@published)
214
- str
215
- end
216
- end
217
-
218
4
  # HMC information
219
5
  class ManagementConsole < AbstractRest
220
6
  ATTRS = {
@@ -240,7 +26,7 @@ module IbmPowerHmc
240
26
  }.freeze
241
27
 
242
28
  def time
243
- Time.at(0, singleton("ManagementConsoleTime").to_i, :millisecond).utc
29
+ timestamp("ManagementConsoleTime")
244
30
  end
245
31
 
246
32
  def managed_systems_uuids
@@ -283,7 +69,7 @@ module IbmPowerHmc
283
69
  end
284
70
 
285
71
  def time
286
- Time.at(0, singleton("SystemTime").to_i, :millisecond).utc
72
+ timestamp("SystemTime")
287
73
  end
288
74
 
289
75
  def capabilities
@@ -352,6 +138,7 @@ module IbmPowerHmc
352
138
  :procs => "PartitionProcessorConfiguration/CurrentDedicatedProcessorConfiguration/CurrentProcessors",
353
139
  :proc_units => "PartitionProcessorConfiguration/CurrentSharedProcessorConfiguration/CurrentProcessingUnits",
354
140
  :vprocs => "PartitionProcessorConfiguration/CurrentSharedProcessorConfiguration/AllocatedVirtualProcessors",
141
+ :cpu_compat_mode => "CurrentProcessorCompatibilityMode",
355
142
  :description => "Description"
356
143
  }.freeze
357
144
 
@@ -419,6 +206,14 @@ module IbmPowerHmc
419
206
  def vfc_mappings
420
207
  collection_of("VirtualFibreChannelMappings", "VirtualFibreChannelMapping")
421
208
  end
209
+
210
+ def seas
211
+ collection_of("SharedEthernetAdapters", "SharedEthernetAdapter")
212
+ end
213
+
214
+ def trunks
215
+ collection_of("TrunkAdapters", "TrunkAdapter")
216
+ end
422
217
  end
423
218
 
424
219
  # Group information
@@ -442,6 +237,53 @@ module IbmPowerHmc
442
237
  end
443
238
  end
444
239
 
240
+ # SEA information
241
+ class SharedEthernetAdapter < AbstractNonRest
242
+ ATTRS = {
243
+ :udid => "UniqueDeviceID",
244
+ :name => "DeviceName",
245
+ :state => "ConfigurationState",
246
+ :large_send => "LargeSend",
247
+ :vlan_id => "PortVLANID",
248
+ :ha_mode => "HighAvailabilityMode",
249
+ :qos_mode => "QualityOfServiceMode",
250
+ :jumbo => "JumboFramesEnabled",
251
+ :queue_size => "QueueSize",
252
+ :primary => "IsPrimary"
253
+ }.freeze
254
+
255
+ def iface
256
+ elem = xml.elements["IPInterface"]
257
+ IPInterface.new(elem) unless elem.nil?
258
+ end
259
+
260
+ def device
261
+ elem = xml.elements["BackingDeviceChoice/*[1]"]
262
+ begin
263
+ Module.const_get("IbmPowerHmc::#{elem.name}").new(elem) unless elem.nil?
264
+ rescue NameError
265
+ nil
266
+ end
267
+ end
268
+
269
+ def trunks
270
+ collection_of("TrunkAdapters", "TrunkAdapter")
271
+ end
272
+ end
273
+
274
+ # IP Interface information
275
+ class IPInterface < AbstractNonRest
276
+ ATTRS = {
277
+ :name => "InterfaceName",
278
+ :state => "State",
279
+ :hostname => "HostName",
280
+ :ip => "IPAddress",
281
+ :netmask => "SubnetMask",
282
+ :gateway => "Gateway",
283
+ :prefix => "IPV6Prefix",
284
+ }.freeze
285
+ end
286
+
445
287
  # Empty parent class to match K2 schema definition
446
288
  class VirtualSCSIStorage < AbstractNonRest; end
447
289
 
@@ -552,6 +394,7 @@ module IbmPowerHmc
552
394
  # Virtual Ethernet Adapter information
553
395
  class VirtualEthernetAdapter < VirtualIOAdapter
554
396
  ATTRS = ATTRS.merge({
397
+ :name => "DeviceName",
555
398
  :macaddr => "MACAddress",
556
399
  :vswitch_id => "VirtualSwitchID",
557
400
  :vlan_id => "PortVLANID",
@@ -570,9 +413,17 @@ module IbmPowerHmc
570
413
  end
571
414
  end
572
415
 
573
- # LP-HEA information
574
- class EthernetBackingDevice < IOAdapter; end
416
+ # Trunk Adapter information
417
+ class TrunkAdapter < VirtualEthernetAdapter; end
575
418
 
419
+ class EthernetBackingDevice < IOAdapter
420
+ def iface
421
+ elem = xml.elements["IPInterface"]
422
+ IPInterface.new(elem) unless elem.nil?
423
+ end
424
+ end
425
+
426
+ # LP-HEA information
576
427
  class HostEthernetAdapterLogicalPort < EthernetBackingDevice
577
428
  ATTRS = ATTRS.merge({
578
429
  :macaddr => "MACAddress",
@@ -944,110 +795,6 @@ module IbmPowerHmc
944
795
  end
945
796
  end
946
797
 
947
- class PartitionTemplateSummary < AbstractRest
948
- ATTRS = {
949
- :name => "partitionTemplateName"
950
- }.freeze
951
- end
952
-
953
- class PartitionTemplate < AbstractRest
954
- ATTRS = {
955
- :name => "partitionTemplateName",
956
- :description => "description",
957
- :lpar_name => "logicalPartitionConfig/partitionName",
958
- :lpar_type => "logicalPartitionConfig/partitionType",
959
- :lpar_id => "logicalPartitionConfig/partitionId",
960
- :os => "logicalPartitionConfig/osVersion",
961
- :memory => "logicalPartitionConfig/memoryConfiguration/currMemory",
962
- :dedicated => "logicalPartitionConfig/processorConfiguration/hasDedicatedProcessors",
963
- :sharing_mode => "logicalPartitionConfig/processorConfiguration/sharingMode",
964
- :vprocs => "logicalPartitionConfig/processorConfiguration/sharedProcessorConfiguration/desiredVirtualProcessors",
965
- :proc_units => "logicalPartitionConfig/processorConfiguration/sharedProcessorConfiguration/desiredProcessingUnits",
966
- :procs => "logicalPartitionConfig/processorConfiguration/dedicatedProcessorConfiguration/desiredProcessors"
967
- }.freeze
968
-
969
- def vscsi
970
- REXML::XPath.match(xml, 'logicalPartitionConfig/virtualSCSIClientAdapters/VirtualSCSIClientAdapter').map do |adap|
971
- {
972
- :vios => adap.elements['connectingPartitionName']&.text,
973
- :physvol => adap.elements['associatedPhysicalVolume/PhysicalVolume/name']&.text,
974
- }
975
- end
976
- end
977
-
978
- def vscsi=(list = [])
979
- adaps = REXML::Element.new('virtualSCSIClientAdapters')
980
- adaps.add_attribute('schemaVersion', 'V1_5_0')
981
- list.each do |vscsi|
982
- adaps.add_element('VirtualSCSIClientAdapter', {'schemaVersion' => 'V1_5_0'}).tap do |v|
983
- v.add_element('associatedLogicalUnits', {'schemaVersion' => 'V1_5_0'})
984
- v.add_element('associatedPhysicalVolume', {'schemaVersion' => 'V1_5_0'}).tap do |e|
985
- e.add_element('PhysicalVolume', {'schemaVersion' => 'V1_5_0'}).add_element('name').text = vscsi[:physvol] if vscsi[:physvol]
986
- end
987
- v.add_element('connectingPartitionName').text = vscsi[:vios]
988
- v.add_element('AssociatedTargetDevices', {'schemaVersion' => 'V1_5_0'})
989
- v.add_element('associatedVirtualOpticalMedia', {'schemaVersion' => 'V1_5_0'})
990
- end
991
- end
992
- if xml.elements['logicalPartitionConfig/virtualSCSIClientAdapters']
993
- xml.elements['logicalPartitionConfig/virtualSCSIClientAdapters'] = adaps
994
- else
995
- xml.elements['logicalPartitionConfig'].add_element(adaps)
996
- end
997
- end
998
-
999
- def vfc
1000
- REXML::XPath.match(xml, 'logicalPartitionConfig/virtualFibreChannelClientAdapters/VirtualFibreChannelClientAdapter').map do |adap|
1001
- {
1002
- :vios => adap.elements['connectingPartitionName']&.text,
1003
- :port => adap.elements['portName']&.text
1004
- }
1005
- end
1006
- end
1007
-
1008
- def vfc=(list = [])
1009
- adaps = REXML::Element.new('virtualFibreChannelClientAdapters')
1010
- adaps.add_attribute('schemaVersion', 'V1_5_0')
1011
- list.each do |vfc|
1012
- adaps.add_element('VirtualFibreChannelClientAdapter', {'schemaVersion' => 'V1_5_0'}).tap do |v|
1013
- v.add_element('connectingPartitionName').text = vfc[:vios]
1014
- v.add_element('portName').text = vfc[:port]
1015
- end
1016
- end
1017
- if xml.elements['logicalPartitionConfig/virtualFibreChannelClientAdapters']
1018
- xml.elements['logicalPartitionConfig/virtualFibreChannelClientAdapters'] = adaps
1019
- else
1020
- xml.elements['logicalPartitionConfig'].add_element(adaps)
1021
- end
1022
- end
1023
-
1024
- def vlans
1025
- REXML::XPath.match(xml, 'logicalPartitionConfig/clientNetworkAdapters/ClientNetworkAdapter/clientVirtualNetworks/ClientVirtualNetwork').map do |vlan|
1026
- {
1027
- :name => vlan.elements['name']&.text,
1028
- :vlan_id => vlan.elements['vlanId']&.text,
1029
- :switch => vlan.elements['associatedSwitchName']&.text
1030
- }
1031
- end
1032
- end
1033
-
1034
- def vlans=(list = [])
1035
- adaps = REXML::Element.new('clientNetworkAdapters')
1036
- adaps.add_attribute('schemaVersion', 'V1_5_0')
1037
- list.each do |vlan|
1038
- adaps.add_element('ClientNetworkAdapter', {'schemaVersion' => 'V1_5_0'})
1039
- .add_element('clientVirtualNetworks', {'schemaVersion' => 'V1_5_0'})
1040
- .add_element('ClientVirtualNetwork', {'schemaVersion' => 'V1_5_0'})
1041
- .tap do |v|
1042
- v.add_element('name').text = vlan[:name]
1043
- v.add_element('vlanId').text = vlan[:vlan_id]
1044
- v.add_element('associatedSwitchName').text = vlan[:switch]
1045
- end
1046
- end
1047
- xml.elements['logicalPartitionConfig/clientNetworkAdapters'] = adaps
1048
- end
1049
- end
1050
-
1051
798
  # HMC Event
1052
799
  class Event < AbstractRest
1053
800
  attr_accessor :usertask
@@ -1060,16 +807,6 @@ module IbmPowerHmc
1060
807
  }.freeze
1061
808
  end
1062
809
 
1063
- # Error response from HMC
1064
- class HttpErrorResponse < AbstractRest
1065
- ATTRS = {
1066
- :status => "HTTPStatus",
1067
- :uri => "RequestURI",
1068
- :reason => "ReasonCode",
1069
- :message => "Message"
1070
- }.freeze
1071
- end
1072
-
1073
810
  # Job Response
1074
811
  class JobResponse < AbstractRest
1075
812
  ATTRS = {
@@ -1090,32 +827,4 @@ module IbmPowerHmc
1090
827
  results
1091
828
  end
1092
829
  end
1093
-
1094
- # Performance and Capacity Monitoring preferences
1095
- class ManagementConsolePcmPreference < AbstractRest
1096
- ATTRS = {
1097
- :max_ltm => "MaximumManagedSystemsForLongTermMonitor",
1098
- :max_compute_ltm => "MaximumManagedSystemsForComputeLTM",
1099
- :max_aggregation => "MaximumManagedSystemsForAggregation",
1100
- :max_stm => "MaximumManagedSystemsForShortTermMonitor",
1101
- :max_em => "MaximumManagedSystemsForEnergyMonitor",
1102
- :aggregated_storage_duration => "AggregatedMetricsStorageDuration"
1103
- }.freeze
1104
-
1105
- def managed_system_preferences
1106
- collection_of(nil, "ManagedSystemPcmPreference")
1107
- end
1108
- end
1109
-
1110
- class ManagedSystemPcmPreference < AbstractNonRest
1111
- ATTRS = {
1112
- :id => "Metadata/Atom/AtomID",
1113
- :name => "SystemName",
1114
- :long_term_monitor => "LongTermMonitorEnabled",
1115
- :aggregation => "AggregationEnabled",
1116
- :short_term_monitor => "ShortTermMonitorEnabled",
1117
- :compute_ltm => "ComputeLTMEnabled",
1118
- :energy_monitor => "EnergyMonitorEnabled"
1119
- }.freeze
1120
- end
1121
830
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IbmPowerHmc
4
- VERSION = "0.17.0"
4
+ VERSION = "0.19.0"
5
5
  end
data/lib/ibm_power_hmc.rb CHANGED
@@ -7,8 +7,15 @@ 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/parser"
11
- require_relative "./ibm_power_hmc/job"
12
- require_relative "./ibm_power_hmc/connection"
13
- require_relative "./ibm_power_hmc/pcm"
10
+ require_relative "./ibm_power_hmc/apis/connection"
11
+ require_relative "./ibm_power_hmc/apis/job"
12
+ require_relative "./ibm_power_hmc/apis/pcm"
13
+ require_relative "./ibm_power_hmc/apis/sem"
14
+ require_relative "./ibm_power_hmc/apis/templates"
15
+ require_relative "./ibm_power_hmc/apis/uom"
16
+ require_relative "./ibm_power_hmc/schema/parser"
17
+ require_relative "./ibm_power_hmc/schema/pcm"
18
+ require_relative "./ibm_power_hmc/schema/sem"
19
+ require_relative "./ibm_power_hmc/schema/templates"
20
+ require_relative "./ibm_power_hmc/schema/uom"
14
21
  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.17.0
4
+ version: 0.19.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-13 00:00:00.000000000 Z
11
+ date: 2022-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -56,10 +56,17 @@ files:
56
56
  - bin/setup
57
57
  - ibm_power_hmc.gemspec
58
58
  - lib/ibm_power_hmc.rb
59
- - lib/ibm_power_hmc/connection.rb
60
- - lib/ibm_power_hmc/job.rb
61
- - lib/ibm_power_hmc/parser.rb
62
- - lib/ibm_power_hmc/pcm.rb
59
+ - lib/ibm_power_hmc/apis/connection.rb
60
+ - lib/ibm_power_hmc/apis/job.rb
61
+ - lib/ibm_power_hmc/apis/pcm.rb
62
+ - lib/ibm_power_hmc/apis/sem.rb
63
+ - lib/ibm_power_hmc/apis/templates.rb
64
+ - lib/ibm_power_hmc/apis/uom.rb
65
+ - lib/ibm_power_hmc/schema/parser.rb
66
+ - lib/ibm_power_hmc/schema/pcm.rb
67
+ - lib/ibm_power_hmc/schema/sem.rb
68
+ - lib/ibm_power_hmc/schema/templates.rb
69
+ - lib/ibm_power_hmc/schema/uom.rb
63
70
  - lib/ibm_power_hmc/version.rb
64
71
  homepage: http://github.com/IBM/ibm_power_hmc_sdk_ruby
65
72
  licenses: