opennebula 7.4.0 → 7.4.2

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: fb204ddb718d3acabb9ac069a732d872ed6d3656dcc16ea541ff3b71ab63c1a7
4
- data.tar.gz: cf84fc9b76cac316cd1c254d8bc40767d8c976bc35c3eebac276841d78a3e399
3
+ metadata.gz: 1d17542561cef24c9da0c906782be3a100c3c9b5743af3888b8fd510a206d545
4
+ data.tar.gz: 10a68147329ce1a6f1dc7c28601a9c55f8520fe256c8920d8832119d33c640c1
5
5
  SHA512:
6
- metadata.gz: 1a1b068533aae4f3be591b5cc80efdb9753cb388d1e65548134b50a609acc54264b2d362e67eaf8a561916da92daca77e27d5f7ad5d1cb6b68fbc4c8529a9ab7
7
- data.tar.gz: 0f753b9d7ca107cc3078803d704996d9726cbd290d97c9f6b512cf6871d64ed8a0d2f67d42a7c5d0d6f8cb0a8a98471b1b5c68ee8d3d504f4e8f4d3bca4afab3
6
+ metadata.gz: 5ab098743c89d8750bf9d4183c4264cda28678078ffc8806abbee23fa97cd47dab3f258ea4201f7713d91d7827feb7a67342a33b090a9376c9acbe7a2e913a47
7
+ data.tar.gz: fa56284ce00bbabc72c176712effa08d1ab1abb04173b7a8a486cbab72036777b9648b550fbfb8e43a04b2a5c4de5c00b40a85a477e02cd1b7c0ae3cbcfb80f2
@@ -51,7 +51,7 @@ end
51
51
  module CloudClient
52
52
 
53
53
  # OpenNebula version
54
- VERSION = '7.4.0'
54
+ VERSION = '7.4.2'
55
55
 
56
56
  # #########################################################################
57
57
  # Default location for the authentication file
@@ -168,14 +168,13 @@ module OpenNebula
168
168
  # Return true if the service can be undeployed
169
169
  # @return true if the service can be undeployed, false otherwise
170
170
  def can_undeploy?
171
- # rubocop:disable Style/IfWithBooleanLiteralBranches
171
+ # rubocop:disable-next Style/IfWithBooleanLiteralBranches
172
172
  if (transient_state? && state != Service::STATE['UNDEPLOYING']) ||
173
173
  state == Service::STATE['DONE'] || failed_state?
174
174
  false
175
175
  else
176
176
  true
177
177
  end
178
- # rubocop:enable Style/IfWithBooleanLiteralBranches
179
178
  end
180
179
 
181
180
  # Return true if the service can be updated
data/lib/models.rb CHANGED
@@ -16,9 +16,7 @@
16
16
 
17
17
  require 'opennebula'
18
18
 
19
- # rubocop:disable Style/MixinUsage
20
19
  include OpenNebula
21
- # rubocop:enable Style/MixinUsage
22
20
 
23
21
  require 'opennebula/document_json'
24
22
  require 'opennebula/document_pool_json'
@@ -148,13 +148,12 @@ module OpenNebula
148
148
  #
149
149
  # @return [nil, OpenNebula::Error] nil in case of success, Error
150
150
  # otherwise
151
- # rubocop:disable Metrics/ParameterLists
151
+ # rubocop:disable-next Metrics/ParameterLists
152
152
  def chmod(owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u,
153
153
  other_m, other_a)
154
154
  call(BACKUPJOB_METHODS[:chmod], @pe_id, owner_u, owner_m, owner_a, group_u,
155
155
  group_m, group_a, other_u, other_m, other_a)
156
156
  end
157
- # rubocop:enable Metrics/ParameterLists
158
157
 
159
158
  # Renames this Backup Job
160
159
  #
@@ -311,9 +311,8 @@ module OpenNebula
311
311
  ]
312
312
 
313
313
  def self.init_default_vn_name_template(vn_name_template)
314
- # rubocop:disable Style/ClassVars
314
+ # rubocop:disable-next Style/ClassVars
315
315
  @@vn_name_template = vn_name_template
316
- # rubocop:enable Style/ClassVars
317
316
  end
318
317
 
319
318
  DOCUMENT_TYPE = 101
@@ -18,7 +18,7 @@
18
18
  # exposed through the OpenNebula XMLRPC API. The extensions include
19
19
  # - mp_import helper that imports a template into a marketplace
20
20
  #
21
- # rubocop:disable Style/ClassAndModuleChildren
21
+ # rubocop:disable-next Style/ClassAndModuleChildren
22
22
  module OpenNebula::ServiceTemplateExt
23
23
 
24
24
  def self.extend_object(obj)
@@ -80,4 +80,3 @@ module OpenNebula::ServiceTemplateExt
80
80
  end
81
81
 
82
82
  end
83
- # rubocop:enable Style/ClassAndModuleChildren
@@ -7,7 +7,7 @@ require 'google/protobuf'
7
7
  require 'shared_pb'
8
8
 
9
9
 
10
- descriptor_data = "\n\x08vn.proto\x12\x06one.vn\x1a\x0cshared.proto\"K\n\x0f\x41llocateRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x10\n\x08template\x18\x02 \x01(\t\x12\x12\n\ncluster_id\x18\x03 \x01(\x11\"0\n\rDeleteRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\"?\n\x0bInfoRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x0f\n\x07\x64\x65\x63rypt\x18\x03 \x01(\x08\"R\n\rUpdateRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\x12\x0e\n\x06\x61ppend\x18\x04 \x01(\x05\">\n\rRenameRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x0c\n\x04name\x18\x03 \x01(\t\"\xe6\x01\n\x0c\x43hmodRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08user_use\x18\x03 \x01(\x11\x12\x13\n\x0buser_manage\x18\x04 \x01(\x11\x12\x12\n\nuser_admin\x18\x05 \x01(\x11\x12\x11\n\tgroup_use\x18\x06 \x01(\x11\x12\x14\n\x0cgroup_manage\x18\x07 \x01(\x11\x12\x13\n\x0bgroup_admin\x18\x08 \x01(\x11\x12\x11\n\tother_use\x18\t \x01(\x11\x12\x14\n\x0cother_manage\x18\n \x01(\x11\x12\x13\n\x0bother_admin\x18\x0b \x01(\x11\"R\n\x0c\x43hownRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x0f\n\x07user_id\x18\x03 \x01(\x11\x12\x10\n\x08group_id\x18\x04 \x01(\x11\"K\n\x0bLockRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\r\n\x05level\x18\x03 \x01(\x05\x12\x0c\n\x04test\x18\x04 \x01(\x08\"0\n\rUnlockRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\"A\n\x0c\x41\x64\x64\x41RRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"L\n\x0bRmARRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\r\n\x05\x61r_id\x18\x03 \x01(\x05\x12\r\n\x05\x66orce\x18\x04 \x01(\x08\"D\n\x0fUpdateARRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"C\n\x0eReserveRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"?\n\rFreeARRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\r\n\x05\x61r_id\x18\x03 \x01(\x05\"@\n\x0bHoldRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"C\n\x0eReleaseRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"D\n\x0eRecoverRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x11\n\toperation\x18\x03 \x01(\x05\"V\n\x0fPoolInfoRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66ilter_flag\x18\x02 \x01(\x11\x12\r\n\x05start\x18\x03 \x01(\x11\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x11\x32\x99\x07\n\x15VirtualNetworkService\x12\x34\n\x08\x41llocate\x12\x17.one.vn.AllocateRequest\x1a\x0f.one.ResponseID\x12\x30\n\x06\x44\x65lete\x12\x15.one.vn.DeleteRequest\x1a\x0f.one.ResponseID\x12-\n\x04Info\x12\x13.one.vn.InfoRequest\x1a\x10.one.ResponseXML\x12\x30\n\x06Update\x12\x15.one.vn.UpdateRequest\x1a\x0f.one.ResponseID\x12\x30\n\x06Rename\x12\x15.one.vn.RenameRequest\x1a\x0f.one.ResponseID\x12.\n\x05\x43hmod\x12\x14.one.vn.ChmodRequest\x1a\x0f.one.ResponseID\x12.\n\x05\x43hown\x12\x14.one.vn.ChownRequest\x1a\x0f.one.ResponseID\x12,\n\x04Lock\x12\x13.one.vn.LockRequest\x1a\x0f.one.ResponseID\x12\x30\n\x06Unlock\x12\x15.one.vn.UnlockRequest\x1a\x0f.one.ResponseID\x12.\n\x05\x41\x64\x64\x41R\x12\x14.one.vn.AddARRequest\x1a\x0f.one.ResponseID\x12,\n\x04RmAR\x12\x13.one.vn.RmARRequest\x1a\x0f.one.ResponseID\x12\x34\n\x08UpdateAR\x12\x17.one.vn.UpdateARRequest\x1a\x0f.one.ResponseID\x12\x32\n\x07Reserve\x12\x16.one.vn.ReserveRequest\x1a\x0f.one.ResponseID\x12\x30\n\x06\x46reeAR\x12\x15.one.vn.FreeARRequest\x1a\x0f.one.ResponseID\x12,\n\x04Hold\x12\x13.one.vn.HoldRequest\x1a\x0f.one.ResponseID\x12\x32\n\x07Release\x12\x16.one.vn.ReleaseRequest\x1a\x0f.one.ResponseID\x12\x32\n\x07Recover\x12\x16.one.vn.RecoverRequest\x1a\x0f.one.ResponseID\x12\x35\n\x08PoolInfo\x12\x17.one.vn.PoolInfoRequest\x1a\x10.one.ResponseXMLB6Z4github.com/OpenNebula/one/src/oca/go/src/goca/api/vnb\x06proto3"
10
+ descriptor_data = "\n\x08vn.proto\x12\x06one.vn\x1a\x0cshared.proto\"K\n\x0f\x41llocateRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x10\n\x08template\x18\x02 \x01(\t\x12\x12\n\ncluster_id\x18\x03 \x01(\x11\"0\n\rDeleteRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\"?\n\x0bInfoRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x0f\n\x07\x64\x65\x63rypt\x18\x03 \x01(\x08\"R\n\rUpdateRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\x12\x0e\n\x06\x61ppend\x18\x04 \x01(\x05\">\n\rRenameRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x0c\n\x04name\x18\x03 \x01(\t\"\xe6\x01\n\x0c\x43hmodRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08user_use\x18\x03 \x01(\x11\x12\x13\n\x0buser_manage\x18\x04 \x01(\x11\x12\x12\n\nuser_admin\x18\x05 \x01(\x11\x12\x11\n\tgroup_use\x18\x06 \x01(\x11\x12\x14\n\x0cgroup_manage\x18\x07 \x01(\x11\x12\x13\n\x0bgroup_admin\x18\x08 \x01(\x11\x12\x11\n\tother_use\x18\t \x01(\x11\x12\x14\n\x0cother_manage\x18\n \x01(\x11\x12\x13\n\x0bother_admin\x18\x0b \x01(\x11\"R\n\x0c\x43hownRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x0f\n\x07user_id\x18\x03 \x01(\x11\x12\x10\n\x08group_id\x18\x04 \x01(\x11\"K\n\x0bLockRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\r\n\x05level\x18\x03 \x01(\x05\x12\x0c\n\x04test\x18\x04 \x01(\x08\"0\n\rUnlockRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\"A\n\x0c\x41\x64\x64\x41RRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"L\n\x0bRmARRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\r\n\x05\x61r_id\x18\x03 \x01(\x05\x12\r\n\x05\x66orce\x18\x04 \x01(\x08\"D\n\x0fUpdateARRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"C\n\x0eReserveRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"?\n\rFreeARRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\r\n\x05\x61r_id\x18\x03 \x01(\x05\"@\n\x0bHoldRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"C\n\x0eReleaseRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"D\n\x0eRecoverRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x11\n\toperation\x18\x03 \x01(\x05\"V\n\x0fPoolInfoRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66ilter_flag\x18\x02 \x01(\x11\x12\r\n\x05start\x18\x03 \x01(\x11\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x11\"H\n\x13MirrorCreateRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x10\n\x08template\x18\x03 \x01(\t\"k\n\x13MirrorUpdateRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x11\n\tmirror_id\x18\x03 \x01(\x05\x12\x10\n\x08template\x18\x04 \x01(\t\x12\x0e\n\x06\x61ppend\x18\x05 \x01(\x05\"V\n\x11MirrorPortRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x11\n\tmirror_id\x18\x03 \x01(\x05\x12\r\n\x05ports\x18\x04 \x01(\t\"I\n\x13MirrorDeleteRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0b\n\x03oid\x18\x02 \x01(\x05\x12\x11\n\tmirror_id\x18\x03 \x01(\x05\x32\xcd\t\n\x15VirtualNetworkService\x12\x34\n\x08\x41llocate\x12\x17.one.vn.AllocateRequest\x1a\x0f.one.ResponseID\x12\x30\n\x06\x44\x65lete\x12\x15.one.vn.DeleteRequest\x1a\x0f.one.ResponseID\x12-\n\x04Info\x12\x13.one.vn.InfoRequest\x1a\x10.one.ResponseXML\x12\x30\n\x06Update\x12\x15.one.vn.UpdateRequest\x1a\x0f.one.ResponseID\x12\x30\n\x06Rename\x12\x15.one.vn.RenameRequest\x1a\x0f.one.ResponseID\x12.\n\x05\x43hmod\x12\x14.one.vn.ChmodRequest\x1a\x0f.one.ResponseID\x12.\n\x05\x43hown\x12\x14.one.vn.ChownRequest\x1a\x0f.one.ResponseID\x12,\n\x04Lock\x12\x13.one.vn.LockRequest\x1a\x0f.one.ResponseID\x12\x30\n\x06Unlock\x12\x15.one.vn.UnlockRequest\x1a\x0f.one.ResponseID\x12.\n\x05\x41\x64\x64\x41R\x12\x14.one.vn.AddARRequest\x1a\x0f.one.ResponseID\x12,\n\x04RmAR\x12\x13.one.vn.RmARRequest\x1a\x0f.one.ResponseID\x12\x34\n\x08UpdateAR\x12\x17.one.vn.UpdateARRequest\x1a\x0f.one.ResponseID\x12\x32\n\x07Reserve\x12\x16.one.vn.ReserveRequest\x1a\x0f.one.ResponseID\x12\x30\n\x06\x46reeAR\x12\x15.one.vn.FreeARRequest\x1a\x0f.one.ResponseID\x12,\n\x04Hold\x12\x13.one.vn.HoldRequest\x1a\x0f.one.ResponseID\x12\x32\n\x07Release\x12\x16.one.vn.ReleaseRequest\x1a\x0f.one.ResponseID\x12\x32\n\x07Recover\x12\x16.one.vn.RecoverRequest\x1a\x0f.one.ResponseID\x12<\n\x0cMirrorCreate\x12\x1b.one.vn.MirrorCreateRequest\x1a\x0f.one.ResponseID\x12<\n\x0cMirrorUpdate\x12\x1b.one.vn.MirrorUpdateRequest\x1a\x0f.one.ResponseID\x12;\n\rMirrorAddPort\x12\x19.one.vn.MirrorPortRequest\x1a\x0f.one.ResponseID\x12;\n\rMirrorDelPort\x12\x19.one.vn.MirrorPortRequest\x1a\x0f.one.ResponseID\x12<\n\x0cMirrorDelete\x12\x1b.one.vn.MirrorDeleteRequest\x1a\x0f.one.ResponseID\x12\x35\n\x08PoolInfo\x12\x17.one.vn.PoolInfoRequest\x1a\x10.one.ResponseXMLB6Z4github.com/OpenNebula/one/src/oca/go/src/goca/api/vnb\x06proto3"
11
11
 
12
12
  pool = ::Google::Protobuf::DescriptorPool.generated_pool
13
13
  pool.add_serialized_file(descriptor_data)
@@ -32,5 +32,9 @@ module One
32
32
  ReleaseRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.vn.ReleaseRequest").msgclass
33
33
  RecoverRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.vn.RecoverRequest").msgclass
34
34
  PoolInfoRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.vn.PoolInfoRequest").msgclass
35
+ MirrorCreateRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.vn.MirrorCreateRequest").msgclass
36
+ MirrorUpdateRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.vn.MirrorUpdateRequest").msgclass
37
+ MirrorPortRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.vn.MirrorPortRequest").msgclass
38
+ MirrorDeleteRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.vn.MirrorDeleteRequest").msgclass
35
39
  end
36
40
  end
@@ -62,6 +62,11 @@ module One
62
62
  rpc :Hold, ::One::Vn::HoldRequest, ::One::ResponseID
63
63
  rpc :Release, ::One::Vn::ReleaseRequest, ::One::ResponseID
64
64
  rpc :Recover, ::One::Vn::RecoverRequest, ::One::ResponseID
65
+ rpc :MirrorCreate, ::One::Vn::MirrorCreateRequest, ::One::ResponseID
66
+ rpc :MirrorUpdate, ::One::Vn::MirrorUpdateRequest, ::One::ResponseID
67
+ rpc :MirrorAddPort, ::One::Vn::MirrorPortRequest, ::One::ResponseID
68
+ rpc :MirrorDelPort, ::One::Vn::MirrorPortRequest, ::One::ResponseID
69
+ rpc :MirrorDelete, ::One::Vn::MirrorDeleteRequest, ::One::ResponseID
65
70
  rpc :PoolInfo, ::One::Vn::PoolInfoRequest, ::One::ResponseXML
66
71
  end
67
72
 
@@ -20,7 +20,7 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'grpc')
20
20
 
21
21
  require 'lib/grpc_map_loader'
22
22
 
23
- # rubocop:disable Style/Documentation
23
+ # rubocop:disable-next Style/Documentation
24
24
  module OpenNebula
25
25
 
26
26
  class GRPCClient
@@ -102,4 +102,3 @@ module OpenNebula
102
102
  end
103
103
 
104
104
  end
105
- # rubocop:enable Style/Documentation
@@ -21,7 +21,7 @@ require 'date'
21
21
  # - Unlock
22
22
  # - Synchronize
23
23
  #
24
- # rubocop:disable Style/ClassAndModuleChildren
24
+ # rubocop:disable-next Style/ClassAndModuleChildren
25
25
  module OpenNebula::LockableExt
26
26
 
27
27
  # Expire timeout for locking operation
@@ -128,9 +128,8 @@ module OpenNebula::LockableExt
128
128
  ]
129
129
 
130
130
  # Get obj class to find parents in lockable class
131
- # rubocop:disable Style/TernaryParentheses
131
+ # rubocop:disable-next Style/TernaryParentheses
132
132
  (obj.is_a? Class) ? o_class = obj : o_class = obj.class
133
- # rubocop:enable Style/TernaryParentheses
134
133
 
135
134
  found = false
136
135
  i_class = o_class
@@ -150,4 +149,3 @@ module OpenNebula::LockableExt
150
149
  end
151
150
 
152
151
  end
153
- # rubocop:enable Style/ClassAndModuleChildren
@@ -21,7 +21,7 @@ require 'opennebula/image_pool'
21
21
  # exposed through the OpenNebula XMLRPC API. The extensions include
22
22
  # - export helper that creates OpenNebula related objects from a given app.
23
23
  #
24
- # rubocop:disable Style/ClassAndModuleChildren
24
+ # rubocop:disable-next Style/ClassAndModuleChildren
25
25
  module OpenNebula::MarketPlaceAppExt
26
26
 
27
27
  include OpenNebula
@@ -539,4 +539,3 @@ module OpenNebula::MarketPlaceAppExt
539
539
  end
540
540
 
541
541
  end
542
- # rubocop:enable Style/ClassAndModuleChildren
@@ -14,307 +14,59 @@
14
14
  # limitations under the License. #
15
15
  #--------------------------------------------------------------------------- #
16
16
 
17
- require 'uri'
18
- require 'base64'
19
- require 'json'
20
-
17
+ require 'opennebula/ods/client'
18
+ require 'opennebula/ods/helpers'
21
19
  require 'opennebula/form/helpers'
22
20
  require 'opennebula/form/drivers'
23
21
  require 'opennebula/form/providers'
24
22
  require 'opennebula/form/provisions'
25
- require 'cloud/CloudClient'
26
-
27
- include CloudCLI
28
23
 
29
24
  module OneForm
30
25
 
31
26
  # OneForm API client
32
- class Client
27
+ class Client < OpenNebula::DocumentServer::Client
33
28
 
34
- DEFAULT_OPTIONS = [
35
- ENDPOINT = {
36
- :name => 'server',
37
- :short => '-s url',
38
- :large => '--server url',
39
- :format => String,
40
- :description => 'OneForm endpoint'
41
- },
42
- USERNAME={
43
- :name => 'username',
44
- :short => '-u name',
45
- :large => '--username name',
46
- :format => String,
47
- :description => 'User name'
48
- },
49
- PASSWORD={
50
- :name => 'password',
51
- :short => '-p pass',
52
- :large => '--password pass',
53
- :format => String,
54
- :description => 'User password'
55
- },
56
- API_VERSION={
57
- :name => 'api_version',
58
- :large => '--api-version version',
59
- :format => String,
60
- :description => 'OneForm API Version to use'
61
- }
62
- ]
29
+ extend OpenNebula::DocumentServer::ClientHelpers
30
+
31
+ DEFAULT_ENDPOINT = 'http://localhost:13013'
32
+ POOLS = {
33
+ :providers => '/providers',
34
+ :provisions => '/provisions'
35
+ }
63
36
 
64
37
  include OneForm::Drivers
65
38
  include OneForm::Providers
66
39
  include OneForm::Provisions
67
40
 
68
41
  def initialize(opts = {})
69
- endpoint = '/.one/oneform_endpoint'
70
- @username = opts[:username] || ENV['ONEFORM_USER']
71
- @password = opts[:password] || ENV['ONEFORM_PASSWORD']
72
-
73
- # By default oneform uses JSON as content type
74
- @content_type = opts[:content_type] || 'application/json'
75
-
76
- # Set API version
77
- @version = opts[:api_version] || ENV['ONEFORM_VERSION'] || 'v1'
78
-
79
- if opts[:url]
80
- url = opts[:url]
81
- elsif ENV['ONEFORM_URL']
82
- url = ENV['ONEFORM_URL']
83
- elsif Dir.home && File.exist?(Dir.home + endpoint)
84
- url = File.read(Dir.home + endpoint).strip
85
- elsif File.exist?('/var/lib/one/.one/oneform_endpoint')
86
- url = File.read('/var/lib/one/.one/oneform_endpoint').strip
87
- else
88
- url = 'http://localhost:13013'
89
- end
90
-
91
- url = url.chomp('/') + "/api/#{@version}"
92
-
93
- if @username.nil? && @password.nil?
94
- if Dir.home && !Dir.home.empty? && ENV['ONE_AUTH'] && File.file?(ENV['ONE_AUTH'])
95
- one_auth = File.read(ENV['ONE_AUTH'])
96
- elsif Dir.home && File.file?(Dir.home + '/.one/one_auth')
97
- one_auth = File.read(Dir.home + '/.one/one_auth')
98
- elsif File.file?('/var/lib/one/.one/one_auth')
99
- one_auth = File.read('/var/lib/one/.one/one_auth')
100
- else
101
- raise 'ONE_AUTH file not present'
102
- end
103
-
104
- one_auth = one_auth.rstrip
105
- @username, @password = one_auth.split(':')
106
- end
107
-
108
- @uri = URI.parse(url)
109
-
110
- @user_agent = "OpenNebula #{CloudClient::VERSION} " <<
111
- "(#{opts[:user_agent]||'Ruby'})"
112
-
113
- @host = nil
114
- @port = nil
115
-
116
- return unless ENV['http_proxy']
117
-
118
- uri_proxy = URI.parse(ENV['http_proxy'])
119
- flag = false
120
-
121
- #  Check if we need to bypass the proxy
122
- if ENV['no_proxy']
123
- ENV['no_proxy'].split(',').each do |item|
124
- item = item.strip
125
-
126
- if (IPAddress @uri.host rescue nil).nil?
127
- if (IPAddress(item) rescue nil).nil?
128
- flag |= (item == @uri.host)
129
- end
130
- else
131
- unless (IPAddress item rescue nil).nil?
132
- flag |= IPAddress(item).include? IPAddress(@uri.host)
133
- end
134
- end
135
- end
136
- end
137
-
138
- return if flag
139
-
140
- @host = uri_proxy.host
141
- @port = uri_proxy.port
42
+ ods_opts = opts[:opts] || {}
43
+ client_opts = {
44
+ :content_type => opts[:content_type] || ods_opts[:content_type],
45
+ :version => opts[:api_version] || opts[:version] || ods_opts[:version],
46
+ :user_agent => opts[:user_agent] || ods_opts[:user_agent] || 'Ruby'
47
+ }.compact
48
+
49
+ super(
50
+ :app_name => 'ONEFORM',
51
+ :username => opts[:username],
52
+ :password => opts[:password],
53
+ :endpoint => opts[:url] || opts[:endpoint],
54
+ :opts => client_opts
55
+ )
142
56
  end
143
57
 
144
58
  private
145
59
 
146
- def get(path, params = {})
147
- uri = build_uri(path, params)
148
- request = Net::HTTP::Proxy(@host, @port)::Get.new(uri, default_headers)
149
- perform_request(uri, request)
60
+ def query_params(params)
61
+ params.reject {|_, value| value.nil? || value == false }
150
62
  end
151
63
 
152
- def post(path, body = {})
153
- uri = build_uri(path)
64
+ def post_with_params(path, params = {})
65
+ uri = build_uri(path, query_params(params))
154
66
  request = Net::HTTP::Proxy(@host, @port)::Post.new(uri, default_headers)
155
- request.body = body.is_a?(String) ? body : body.to_json
156
- perform_request(uri, request)
157
- end
158
-
159
- def put(path, body = {})
160
- uri = build_uri(path)
161
- request = Net::HTTP::Proxy(@host, @port)::Put.new(uri, default_headers)
162
- request.body = body.is_a?(String) ? body : body.to_json
163
67
  perform_request(uri, request)
164
68
  end
165
69
 
166
- def patch(path, body = {})
167
- uri = build_uri(path)
168
- request = Net::HTTP::Proxy(@host, @port)::Patch.new(uri, default_headers)
169
- request.body = body.is_a?(String) ? body : body.to_json
170
- perform_request(uri, request)
171
- end
172
-
173
- def delete(path, params = {})
174
- uri = build_uri(path, params)
175
- request = Net::HTTP::Proxy(@host, @port)::Delete.new(uri, default_headers)
176
- perform_request(uri, request)
177
- end
178
-
179
- def poll_logs(path, params = {})
180
- uri = build_uri(path, params)
181
- request = Net::HTTP::Proxy(@host, @port)::Get.new(uri, default_headers)
182
-
183
- raw_body = nil
184
-
185
- Net::HTTP.start(
186
- uri.host,
187
- uri.port,
188
- :use_ssl => (uri.scheme == 'https')
189
- ) do |http|
190
- response = http.request(request)
191
-
192
- raise "Request failed: #{response.code} #{response.message}" \
193
- unless response.is_a?(Net::HTTPSuccess)
194
-
195
- raw_body = response.body
196
- end
197
-
198
- json =
199
- begin
200
- JSON.parse(raw_body)
201
- rescue JSON::ParserError => e
202
- raise "Invalid JSON response: #{e.message}"
203
- end
204
-
205
- {
206
- :pos => json['pos'],
207
- :meta => json['meta'],
208
- :lines => json['lines'] || []
209
- }
210
- end
211
-
212
- def follow_logs(path, params = {})
213
- pos = params[:all] ? 0 : nil
214
- interval = params[:interval] || 1.0
215
-
216
- loop do
217
- begin
218
- response = poll_logs(path, { :pos => pos })
219
-
220
- response[:lines].each do |entry|
221
- level = entry['level'] || 'info'
222
- text = entry['text'] || ''
223
- puts "[#{level}] #{text}"
224
- end
225
-
226
- pos = response[:pos] || pos
227
- sleep interval
228
- rescue Interrupt
229
- break
230
- rescue StandardError => e
231
- warn "Polling error: #{e.class}: #{e.message}"
232
- sleep interval
233
- end
234
- end
235
- end
236
-
237
- def build_uri(path, params = {})
238
- uri = @uri.dup
239
- path = path.sub(%r{^/}, '')
240
- uri.path = [@uri.path, path].join('/').gsub(%r{/{2,}}, '/')
241
- uri.query = URI.encode_www_form(params) unless params.empty?
242
- uri
243
- end
244
-
245
- def default_headers
246
- auth = Base64.strict_encode64("#{@username}:#{@password}")
247
- {
248
- 'Authorization' => "Basic #{auth}",
249
- 'Content-Type' => @content_type,
250
- 'Accept' => @content_type,
251
- 'User-Agent' => @user_agent
252
- }
253
- end
254
-
255
- def perform_request(uri, request)
256
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
257
- response = http.request(request)
258
- handle_response(response)
259
- end
260
- end
261
-
262
- def handle_response(response)
263
- json = nil
264
-
265
- begin
266
- body = response.body && !response.body.strip.empty? ? response.body : '{}'
267
- json = JSON.parse(body, :symbolize_names => true)
268
- rescue JSON::ParserError
269
- raise "OneForm Error: #{body.inspect}"
270
- end
271
-
272
- case response
273
- when Net::HTTPSuccess
274
- if json.is_a?(Array)
275
- json.map do |item|
276
- item.is_a?(Hash) && item.key?(:DOCUMENT) ? item[:DOCUMENT] : item
277
- end
278
- elsif json.is_a?(Hash) && json.key?(:DOCUMENT)
279
- json[:DOCUMENT]
280
- else
281
- json
282
- end
283
- else
284
- err_code = json[:err_code] || 'UNKNOWN'
285
- error_message = json[:message] || 'No message provided'
286
- err_ctx = json[:context] || {}
287
-
288
- if err_ctx && !err_ctx.empty?
289
- context_str = format_context(err_ctx)
290
-
291
- msg = <<~MSG
292
- OneForm Error (#{err_code}): #{error_message}
293
- #{context_str}
294
- MSG
295
- else
296
- msg = "OneForm Error (#{err_code}): #{error_message}"
297
- end
298
-
299
- raise msg
300
- end
301
- end
302
-
303
- def format_context(hash, indent = 0, top_level = true)
304
- prefix = ' ' * indent
305
-
306
- hash.map do |key, value|
307
- line_prefix = top_level ? "#{prefix}- " : "#{prefix} "
308
-
309
- if value.is_a?(Hash)
310
- nested = format_context(value, indent + 2, false)
311
- "#{line_prefix}#{key}:\n#{nested}"
312
- else
313
- "#{line_prefix}#{key}: #{value}"
314
- end
315
- end.join("\n")
316
- end
317
-
318
70
  end
319
71
 
320
72
  end
@@ -30,7 +30,10 @@ class OpenNebula::ServerCipherAuth
30
30
  #Constants with paths to relevant files and defaults
31
31
  ###########################################################################
32
32
 
33
- CIPHER = "aes-256-cbc"
33
+ CIPHER = 'aes-256-gcm'
34
+ NONCE_SIZE = 12
35
+ TAG_SIZE = 16
36
+ # Token payload: Base64(nonce || ciphertext || authentication tag).
34
37
 
35
38
  ###########################################################################
36
39
 
@@ -41,13 +44,9 @@ class OpenNebula::ServerCipherAuth
41
44
  if !srv_passwd.empty?
42
45
  # truncate token to 32-bytes for Ruby >= 2.4
43
46
  @key = Digest::SHA256.hexdigest(@srv_passwd)[0..31]
44
- @iv = @key[0..15]
45
- else
47
+ else
46
48
  @key = ""
47
- @iv = ""
48
49
  end
49
-
50
- @cipher = OpenSSL::Cipher.new(CIPHER)
51
50
  end
52
51
 
53
52
  ###########################################################################
@@ -89,10 +88,7 @@ class OpenNebula::ServerCipherAuth
89
88
  target_user ||= @srv_user
90
89
  token_txt = "#{@srv_user}:#{target_user}:#{expire}"
91
90
 
92
- token = encrypt(token_txt)
93
- token64 = Base64::encode64(token).strip.delete("\n")
94
-
95
- return "#{@srv_user}:#{target_user}:#{token64}"
91
+ return "#{@srv_user}:#{target_user}:#{encrypt(token_txt)}"
96
92
  end
97
93
 
98
94
  # Returns a valid password string to create a user using this auth driver
@@ -110,47 +106,60 @@ class OpenNebula::ServerCipherAuth
110
106
  end
111
107
 
112
108
  # auth method for auth_mad
113
- def authenticate(srv_user, srv_pass, signed_text)
109
+ def authenticate(srv_user, srv_pass, signed_text, target_user)
114
110
  begin
115
111
  # truncate token to 32-bytes for Ruby >= 2.4
116
112
  @key = srv_pass[0..31]
117
- @iv = srv_pass[0..15]
118
113
 
119
114
  token_array = decrypt(signed_text).split(':')
120
115
 
121
- s_user = token_array[0]
122
- expires = token_array[-1]
116
+ return 'Invalid login token' if target_user.nil? || target_user.empty? ||
117
+ ![3, 4].include?(token_array.length)
118
+
119
+ s_user = token_array.shift
120
+ expires = token_array.pop
121
+ s_target = token_array.join(':')
123
122
 
124
- return "User name missmatch" if s_user != srv_user
123
+ return 'User name mismatch' if s_user != srv_user || s_target != target_user
125
124
 
126
125
  return "login token expired" if Time.now.to_i >= expires.to_i
127
126
 
128
127
  return true
129
- rescue => e
130
- return e.message
128
+ rescue StandardError
129
+ return 'Invalid login token'
131
130
  end
132
131
  end
133
132
 
134
133
  private
135
134
 
136
135
  def encrypt(data)
137
- @cipher.encrypt
138
- @cipher.key = @key
139
- @cipher.iv = @iv
140
- rc = @cipher.update(data)
141
- rc << @cipher.final
142
-
143
- return rc
136
+ cipher = OpenSSL::Cipher.new(CIPHER)
137
+ cipher.encrypt
138
+ cipher.key = @key
139
+ nonce = OpenSSL::Random.random_bytes(NONCE_SIZE)
140
+ cipher.iv = nonce
141
+ cipher.auth_data = ''
142
+ ciphertext = cipher.update(data) + cipher.final
143
+
144
+ Base64.strict_encode64(nonce + ciphertext + cipher.auth_tag(TAG_SIZE))
144
145
  end
145
146
 
146
147
  def decrypt(data)
147
- @cipher.decrypt
148
- @cipher.key = @key
149
- @cipher.iv = @iv
150
- rc = @cipher.update(Base64::decode64(data))
151
- rc << @cipher.final
152
-
153
- return rc
148
+ raw = Base64.strict_decode64(data)
149
+ raise ArgumentError if raw.bytesize <= NONCE_SIZE + TAG_SIZE
150
+
151
+ nonce = raw[0, NONCE_SIZE]
152
+ ciphertext = raw[NONCE_SIZE...-TAG_SIZE]
153
+ tag = raw[-TAG_SIZE, TAG_SIZE]
154
+
155
+ cipher = OpenSSL::Cipher.new(CIPHER)
156
+ cipher.decrypt
157
+ cipher.key = @key
158
+ cipher.iv = nonce
159
+ cipher.auth_tag = tag
160
+ cipher.auth_data = ''
161
+ plaintext = cipher.update(ciphertext)
162
+ plaintext << cipher.final
163
+ plaintext
154
164
  end
155
165
  end
156
-
@@ -85,17 +85,22 @@ class OpenNebula::ServerX509Auth < OpenNebula::X509Auth
85
85
  ###########################################################################
86
86
 
87
87
  # auth method for auth_mad
88
- def authenticate(server_user, server_pass, signed_text)
88
+ def authenticate(server_user, server_pass, signed_text, target_user)
89
89
  begin
90
90
  token_array = decrypt(signed_text).split(':')
91
91
 
92
- s_user = token_array[0]
93
- expires = token_array[-1]
92
+ return 'Invalid login token' if target_user.nil? || target_user.empty? ||
93
+ ![3, 4].include?(token_array.length)
94
+
95
+ s_user = token_array.shift
96
+ expires = token_array.pop
97
+ s_target = token_array.join(':')
94
98
 
95
99
  return "Server password missmatch" if server_pass != password
96
100
 
97
- return "User name missmatch" if ( s_user != server_user ||
98
- s_user != @options[:srv_user] )
101
+ return 'User name mismatch' if s_user != server_user ||
102
+ s_user != @options[:srv_user] ||
103
+ s_target != target_user
99
104
 
100
105
  return "login token expired" if Time.now.to_i >= expires.to_i
101
106
 
@@ -21,7 +21,7 @@ require 'opennebula/wait_ext'
21
21
  # exposed through the OpenNebula XMLRPC API. The extensions include
22
22
  # - mp_import helper that imports a template into a marketplace
23
23
  #
24
- # rubocop:disable Style/ClassAndModuleChildren
24
+ # rubocop:disable-next Style/ClassAndModuleChildren
25
25
  module OpenNebula::TemplateExt
26
26
 
27
27
  def self.extend_object(obj)
@@ -342,4 +342,3 @@ module OpenNebula::TemplateExt
342
342
  end
343
343
 
344
344
  end
345
- # rubocop:enable Style/ClassAndModuleChildren
@@ -17,6 +17,6 @@
17
17
  module OpenNebula
18
18
 
19
19
  # OpenNebula version
20
- VERSION = '7.4.0'
20
+ VERSION = '7.4.2'
21
21
 
22
22
  end
@@ -813,16 +813,25 @@ module OpenNebula
813
813
  end
814
814
  end
815
815
 
816
- # Changes the attributes of a VM in power off, failure and undeploy
817
- # states
816
+ # Changes the attributes of a VM in running, pending, power off, failure,
817
+ # hold, cloning and undeploy states
818
818
  #
819
819
  # @param new_conf, string describing the new attributes. Each attribute
820
820
  # will replace the existing ones or delete it if empty. Attributes that
821
- # can be updated are: INPUT/{TYPE, BUS}; RAW/{TYPE, DATA, DATA_VMX},
822
- # OS/{BOOT, BOOTLOADER, ARCH, MACHINE, KERNEL, INITRD},
823
- # FEATURES/{ACPI, APIC, PAE, LOCALTIME, HYPERV, GUEST_AGENT, VIRTIO_SCSI_QUEUES, VIRTIO_BLK_QUEUES, IOTHREADS},
824
- # GRAPHICS/{TYPE, LISTEN, PASSWD, KEYMAP},
825
- # and VIDEO/{TYPE, IOMMU, ATS, VRAM, RESOLUTION}
821
+ # can be updated are:
822
+ # INPUT/{TYPE, BUS},
823
+ # RAW/{TYPE, DATA, VALIDATE},
824
+ # OS/{ARCH,MACHINE, KERNEL, INITRD, BOOTLOADER, BOOT, KERNEL_CMD,ROOT,
825
+ # SD_DISK_BUS, UUID, FIRMWARE, FIRMWARE_FORMAT},
826
+ # FEATURES/{ACPI, APIC, PAE, LOCALTIME, HYPERV, GUEST_AGENT,
827
+ # VIRTIO_SCSI_QUEUES, VIRTIO_BLK_QUEUES, IOTHREADS, GIC,
828
+ # RAS, MIGRATE_AUTO_CONVERGE, MIGRATE_COMPRESSED},
829
+ # CPU_MODEL/{MODEL, FEATURES},
830
+ # GRAPHICS/{TYPE, LISTEN, PASSWD, KEYMAP, COMMAND},
831
+ # VIDEO/{TYPE, IOMMU, ATS, VRAM, RESOLUTION},
832
+ # BACKUP_CONFIG/{FS_FREEZE, KEEP_LAST, BACKUP_VOLATILE, INCREMENT_MODE,
833
+ # MODE, DISK_IDS, INTERACTIVE}
834
+ # CONTEXT{*}
826
835
  # @param append, append template, do not delete empty attributes
827
836
  # @return [nil, OpenNebula::Error] nil in case of success, Error
828
837
  # otherwise
@@ -20,7 +20,7 @@ require 'opennebula/template_ext'
20
20
  # exposed through the OpenNebula XMLRPC API. The extensions include
21
21
  # - mp_import helper that imports a template into a marketplace
22
22
  #
23
- # rubocop:disable Style/ClassAndModuleChildren
23
+ # rubocop:disable-next Style/ClassAndModuleChildren
24
24
  module OpenNebula::VirtualMachineExt
25
25
 
26
26
  def self.extend_object(obj)
@@ -280,4 +280,3 @@ module OpenNebula::VirtualMachineExt
280
280
  end
281
281
 
282
282
  end
283
- # rubocop:enable Style/ClassAndModuleChildren
@@ -41,7 +41,12 @@ module OpenNebula
41
41
  :free_ar => "vn.free_ar",
42
42
  :lock => "vn.lock",
43
43
  :unlock => "vn.unlock",
44
- :recover => "vn.recover"
44
+ :recover => "vn.recover",
45
+ :mirror_create => 'vn.mirror_create',
46
+ :mirror_update => 'vn.mirror_update',
47
+ :mirror_addport => 'vn.mirror_addport',
48
+ :mirror_delport => 'vn.mirror_delport',
49
+ :mirror_delete => 'vn.mirror_delete',
45
50
  }
46
51
 
47
52
  VN_STATES=%w{INIT READY LOCK_CREATE LOCK_DELETE DONE ERROR UPDATE_FAILURE}
@@ -298,6 +303,58 @@ module OpenNebula
298
303
  return call(VN_METHODS[:recover], @pe_id, result)
299
304
  end
300
305
 
306
+ # Creates a traffic mirror and returns its VNet-scoped ID.
307
+ def mirror_create(mirror_template)
308
+ return Error.new('ID not defined') unless @pe_id
309
+
310
+ @client.call(VN_METHODS[:mirror_create], @pe_id, mirror_template)
311
+ end
312
+
313
+ # Updates mirror configuration. PORTS must be changed separately.
314
+ def mirror_update(mirror_id, mirror_template, append = false)
315
+ return Error.new('ID not defined') unless @pe_id
316
+
317
+ mirror_id_i = Integer(mirror_id.to_s, 10)
318
+
319
+ @client.call(VN_METHODS[:mirror_update], @pe_id, mirror_id_i,
320
+ mirror_template, append ? 1 : 0)
321
+ rescue ArgumentError, TypeError
322
+ Error.new("Invalid mirror ID: #{mirror_id}")
323
+ end
324
+
325
+ # Adds VM_ID:NIC_ID entries to a mirror.
326
+ def mirror_addport(mirror_id, ports)
327
+ return Error.new('ID not defined') unless @pe_id
328
+
329
+ mirror_id_i = Integer(mirror_id.to_s, 10)
330
+
331
+ @client.call(VN_METHODS[:mirror_addport], @pe_id, mirror_id_i, ports)
332
+ rescue ArgumentError, TypeError
333
+ Error.new("Invalid mirror ID: #{mirror_id}")
334
+ end
335
+
336
+ # Removes VM_ID:NIC_ID entries from a mirror.
337
+ def mirror_delport(mirror_id, ports)
338
+ return Error.new('ID not defined') unless @pe_id
339
+
340
+ mirror_id_i = Integer(mirror_id.to_s, 10)
341
+
342
+ @client.call(VN_METHODS[:mirror_delport], @pe_id, mirror_id_i, ports)
343
+ rescue ArgumentError, TypeError
344
+ Error.new("Invalid mirror ID: #{mirror_id}")
345
+ end
346
+
347
+ # Deletes a mirror.
348
+ def mirror_delete(mirror_id)
349
+ return Error.new('ID not defined') unless @pe_id
350
+
351
+ mirror_id_i = Integer(mirror_id.to_s, 10)
352
+
353
+ @client.call(VN_METHODS[:mirror_delete], @pe_id, mirror_id_i)
354
+ rescue ArgumentError, TypeError
355
+ Error.new("Invalid mirror ID: #{mirror_id}")
356
+ end
357
+
301
358
  #######################################################################
302
359
  # Helpers to get VirtualNetwork information
303
360
  #######################################################################
@@ -134,7 +134,7 @@ end
134
134
  # Module to decorate Wait classes with the following methods:
135
135
  # - Wait
136
136
  #
137
- # rubocop:disable Style/ClassAndModuleChildren
137
+ # rubocop:disable-next Style/ClassAndModuleChildren
138
138
  module OpenNebula::WaitExt
139
139
 
140
140
  # Wait classes and the name published in ZMQ/STATE
@@ -269,9 +269,8 @@ module OpenNebula::WaitExt
269
269
  # @param obj [Object or Class] Object to check class
270
270
  def self.wait?(obj)
271
271
  # Get obj class to find parents in wait class
272
- # rubocop:disable Style/TernaryParentheses
272
+ # rubocop:disable-next Style/TernaryParentheses
273
273
  (obj.is_a? Class) ? o_class = obj : o_class = obj.class
274
- # rubocop:enable Style/TernaryParentheses
275
274
 
276
275
  found = false
277
276
  i_class = o_class
@@ -291,4 +290,3 @@ module OpenNebula::WaitExt
291
290
  end
292
291
 
293
292
  end
294
- # rubocop:enable Style/ClassAndModuleChildren
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opennebula
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.4.0
4
+ version: 7.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenNebula
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-27 00:00:00.000000000 Z
11
+ date: 2026-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri