opennebula 7.4.1 → 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 +4 -4
- data/lib/cloud/CloudClient.rb +1 -1
- data/lib/models/service.rb +1 -2
- data/lib/models.rb +0 -2
- data/lib/opennebula/backupjob.rb +1 -2
- data/lib/opennebula/flow/service_template.rb +1 -2
- data/lib/opennebula/flow/service_template_ext.rb +1 -2
- data/lib/opennebula/grpc/vn_pb.rb +5 -1
- data/lib/opennebula/grpc/vn_services_pb.rb +5 -0
- data/lib/opennebula/lib/grpc_client.rb +1 -2
- data/lib/opennebula/lockable_ext.rb +2 -4
- data/lib/opennebula/marketplaceapp_ext.rb +1 -2
- data/lib/opennebula/oneform_client.rb +28 -276
- data/lib/opennebula/server_cipher_auth.rb +41 -32
- data/lib/opennebula/server_x509_auth.rb +10 -5
- data/lib/opennebula/template_ext.rb +1 -2
- data/lib/opennebula/version.rb +1 -1
- data/lib/opennebula/virtual_machine_ext.rb +1 -2
- data/lib/opennebula/virtual_network.rb +58 -1
- data/lib/opennebula/wait_ext.rb +2 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d17542561cef24c9da0c906782be3a100c3c9b5743af3888b8fd510a206d545
|
|
4
|
+
data.tar.gz: 10a68147329ce1a6f1dc7c28601a9c55f8520fe256c8920d8832119d33c640c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ab098743c89d8750bf9d4183c4264cda28678078ffc8806abbee23fa97cd47dab3f258ea4201f7713d91d7827feb7a67342a33b090a9376c9acbe7a2e913a47
|
|
7
|
+
data.tar.gz: fa56284ce00bbabc72c176712effa08d1ab1abb04173b7a8a486cbab72036777b9648b550fbfb8e43a04b2a5c4de5c00b40a85a477e02cd1b7c0ae3cbcfb80f2
|
data/lib/cloud/CloudClient.rb
CHANGED
data/lib/models/service.rb
CHANGED
|
@@ -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
data/lib/opennebula/backupjob.rb
CHANGED
|
@@ -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\
|
|
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 '
|
|
18
|
-
require '
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
|
147
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
122
|
-
|
|
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
|
|
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
|
|
130
|
-
return
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
93
|
-
|
|
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
|
|
98
|
-
|
|
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
|
data/lib/opennebula/version.rb
CHANGED
|
@@ -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
|
#######################################################################
|
data/lib/opennebula/wait_ext.rb
CHANGED
|
@@ -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.
|
|
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-
|
|
11
|
+
date: 2026-11-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: nokogiri
|