opennebula 7.2.0 → 7.2.1
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/opennebula/error.rb +1 -1
- data/lib/opennebula/lib/client.rb +138 -0
- data/lib/opennebula/lib/grpc_client.rb +105 -0
- data/lib/opennebula/lib/xml_client.rb +178 -0
- data/lib/opennebula/version.rb +1 -1
- data/lib/opennebula/virtual_machine_pool.rb +0 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec857d82d9122d895b79906537bc2bdd190c4a8b5ce0af34293fb944b7e222e4
|
|
4
|
+
data.tar.gz: 07f7b9481eb44a0d18d65d81381c65024492d22cba724378f8f598ce97ee5bdc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b23c2de26bd07cb1d8949921ee385cf4746b248028197bbf0e14f3c23f96f6d577e2d76c3db4cf52190ba1542c4b1da606a5b641f76df9d47e5d0fd7cea52df
|
|
7
|
+
data.tar.gz: 7eb669f3a42846376ed7e8423923e86e32767774be0bf854d5797cde069ae8dc5544a5c4a9ce0c9ca2a2cf0664841bd8ce22f38c00658aa13d963d3f18cc99a3
|
data/lib/cloud/CloudClient.rb
CHANGED
data/lib/opennebula/error.rb
CHANGED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
|
2
|
+
# Copyright 2002-2026, OpenNebula Project, OpenNebula Systems #
|
|
3
|
+
# #
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
|
6
|
+
# a copy of the License at #
|
|
7
|
+
# #
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
9
|
+
# #
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
13
|
+
# See the License for the specific language governing permissions and #
|
|
14
|
+
# limitations under the License. #
|
|
15
|
+
#--------------------------------------------------------------------------- #
|
|
16
|
+
|
|
17
|
+
# rubocop:disable Style/Documentation
|
|
18
|
+
# rubocop:disable Style/ClassVars
|
|
19
|
+
# rubocop:disable Style/EnvHome
|
|
20
|
+
# rubocop:disable Naming/AccessorMethodName
|
|
21
|
+
module OpenNebula
|
|
22
|
+
|
|
23
|
+
DEFAULT_POOL_PAGE_SIZE = 200
|
|
24
|
+
size = ENV['ONE_POOL_PAGE_SIZE']
|
|
25
|
+
|
|
26
|
+
@@pool_page_size =
|
|
27
|
+
if size&.strip&.match?(/^\d+$/) && size.to_i >= 2
|
|
28
|
+
size.to_i
|
|
29
|
+
else
|
|
30
|
+
DEFAULT_POOL_PAGE_SIZE
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.pool_page_size
|
|
34
|
+
@@pool_page_size
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Client
|
|
38
|
+
|
|
39
|
+
NO_ONE_AUTH_ERROR = 'ONE_AUTH file not present'
|
|
40
|
+
GRPC_NOT_SUPPORTED = 'gRPC API not supported'
|
|
41
|
+
|
|
42
|
+
attr_reader :client, :one_auth, :one_endpoint, :one_zmq
|
|
43
|
+
|
|
44
|
+
# Initialize an OpenNebula client
|
|
45
|
+
#
|
|
46
|
+
# @param [String, nil] secret user credentials ("user:password") or
|
|
47
|
+
# nil to get the credentials from user auth file
|
|
48
|
+
# @param [String, nil] endpoint OpenNebula server endpoint
|
|
49
|
+
# or nil to get it form the environment or use the default endpoint
|
|
50
|
+
# @param [Hash] options specific XML client options (see XMLClient
|
|
51
|
+
# and GRPCClient for details)
|
|
52
|
+
#
|
|
53
|
+
# @return [OpenNebula::XMLClient || OpenNebula::GRPCClient]
|
|
54
|
+
def initialize(secret = nil, endpoint = nil, options = {})
|
|
55
|
+
if options[:subscriber_endpoint]
|
|
56
|
+
@one_zmq = options[:subscriber_endpoint]
|
|
57
|
+
elsif ENV['ONE_ZMQ']
|
|
58
|
+
@one_zmq = ENV['ONE_ZMQ']
|
|
59
|
+
else
|
|
60
|
+
@one_zmq = 'tcp://localhost:2101'
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
auth_file = File.join(ENV['HOME'], '/.one/one_auth')
|
|
64
|
+
one_auth_file = '/var/lib/one/.one/one_auth'
|
|
65
|
+
|
|
66
|
+
@one_auth =
|
|
67
|
+
if secret
|
|
68
|
+
secret
|
|
69
|
+
elsif ENV['ONE_AUTH'] && File.file?(ENV['ONE_AUTH'])
|
|
70
|
+
File.read(ENV['ONE_AUTH'])
|
|
71
|
+
elsif File.file?(auth_file)
|
|
72
|
+
File.read(auth_file)
|
|
73
|
+
elsif File.file?(one_auth_file)
|
|
74
|
+
File.read(one_auth_file)
|
|
75
|
+
else
|
|
76
|
+
raise NO_ONE_AUTH_ERROR
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
@one_auth = @one_auth.rstrip
|
|
80
|
+
|
|
81
|
+
is_grpc = ENV['ONEAPI_PROTOCOL'] == 'grpc' || options.key?(:grpc)
|
|
82
|
+
|
|
83
|
+
# Override protocol from endpoint name, if endpoint is defined
|
|
84
|
+
is_grpc = !endpoint.include?('RPC2') if !endpoint.nil? && !endpoint.empty?
|
|
85
|
+
|
|
86
|
+
if is_grpc
|
|
87
|
+
begin
|
|
88
|
+
require_relative 'grpc_client'
|
|
89
|
+
rescue LoadError
|
|
90
|
+
raise GRPC_NOT_SUPPORTED
|
|
91
|
+
end
|
|
92
|
+
@one_endpoint = mk_endpoint(endpoint,
|
|
93
|
+
'ONE_GRPC',
|
|
94
|
+
'localhost:2634').rstrip
|
|
95
|
+
|
|
96
|
+
@client = GRPCClient.new(@one_auth, @one_endpoint, options)
|
|
97
|
+
else
|
|
98
|
+
require_relative 'xml_client'
|
|
99
|
+
@one_endpoint = mk_endpoint(endpoint,
|
|
100
|
+
'ONE_XMLRPC',
|
|
101
|
+
'http://localhost:2633/RPC2').rstrip
|
|
102
|
+
|
|
103
|
+
@client = XMLClient.new(@one_auth, @one_endpoint, options)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def call(action, *args)
|
|
108
|
+
@client.call(action, *args)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def get_version
|
|
112
|
+
call('system.version')
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def mk_endpoint(endpoint, env_var, default)
|
|
116
|
+
ep_file = File.join(ENV['HOME'], '/.one/one_endpoint')
|
|
117
|
+
one_ep_file = '/var/lib/one/.one/one_endpoint'
|
|
118
|
+
|
|
119
|
+
if endpoint
|
|
120
|
+
endpoint
|
|
121
|
+
elsif ENV[env_var]
|
|
122
|
+
ENV[env_var]
|
|
123
|
+
elsif File.exist?(ep_file)
|
|
124
|
+
File.read(ep_file)
|
|
125
|
+
elsif File.exist?(one_ep_file)
|
|
126
|
+
File.read(one_ep_file)
|
|
127
|
+
else
|
|
128
|
+
default
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
# rubocop:enable Style/Documentation
|
|
136
|
+
# rubocop:enable Style/ClassVars
|
|
137
|
+
# rubocop:enable Style/EnvHome
|
|
138
|
+
# rubocop:enable Naming/AccessorMethodName
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
|
2
|
+
# Copyright 2002-2026, OpenNebula Project, OpenNebula Systems #
|
|
3
|
+
# #
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
|
6
|
+
# a copy of the License at #
|
|
7
|
+
# #
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
9
|
+
# #
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
13
|
+
# See the License for the specific language governing permissions and #
|
|
14
|
+
# limitations under the License. #
|
|
15
|
+
#--------------------------------------------------------------------------- #
|
|
16
|
+
|
|
17
|
+
require 'grpc'
|
|
18
|
+
|
|
19
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'grpc')
|
|
20
|
+
|
|
21
|
+
require 'lib/grpc_map_loader'
|
|
22
|
+
|
|
23
|
+
# rubocop:disable Style/Documentation
|
|
24
|
+
module OpenNebula
|
|
25
|
+
|
|
26
|
+
class GRPCClient
|
|
27
|
+
|
|
28
|
+
# gRPC mappings from OpenNebula actions to gRPC actions
|
|
29
|
+
GRPC_MAP = GRPCMappings::MapLoader.load
|
|
30
|
+
|
|
31
|
+
# Creates a new gRPC client object that will be used to call OpenNebula
|
|
32
|
+
# functions.
|
|
33
|
+
#
|
|
34
|
+
# @param [String] secret user credentials ("user:password") or
|
|
35
|
+
# nil to get the credentials from user auth file
|
|
36
|
+
# @param [String] endpoint OpenNebula gRPC server endpoint
|
|
37
|
+
# (http://host:2634) or nil to get it from the environment
|
|
38
|
+
# variable ONE_GRPC or use the default endpoint
|
|
39
|
+
#
|
|
40
|
+
# @return [OpenNebula::GRPCClient]
|
|
41
|
+
def initialize(secret, endpoint, options = {})
|
|
42
|
+
@one_auth = secret
|
|
43
|
+
@one_endpoint = endpoint
|
|
44
|
+
@timeout = options[:timeout] || ENV['ONE_GRPC_TIMEOUT']&.to_i
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def call(action, *args)
|
|
48
|
+
handler = GRPC_MAP[action]
|
|
49
|
+
raise Error.new("Method 'one.#{action}' not defined", Error::EGRPC_CALL) unless handler
|
|
50
|
+
|
|
51
|
+
options = {}
|
|
52
|
+
options[:deadline] = Time.now.to_i + @timeout if @timeout
|
|
53
|
+
|
|
54
|
+
response = handler.call(@one_auth, @one_endpoint, *args, options)
|
|
55
|
+
|
|
56
|
+
if response.respond_to?(:oid)
|
|
57
|
+
response.oid
|
|
58
|
+
elsif response.respond_to?(:xml)
|
|
59
|
+
response.xml
|
|
60
|
+
else
|
|
61
|
+
Error.new("Unexpected response: #{response.inspect}", Error::EGRPC_CALL)
|
|
62
|
+
end
|
|
63
|
+
rescue GRPC::DeadlineExceeded
|
|
64
|
+
Error.new("Timeout exceeded for gRPC call '#{action}'", Error::ETIMEOUT)
|
|
65
|
+
rescue GRPC::Unavailable => e
|
|
66
|
+
Error.new("#{action}: #{clean_error_message(e.message)}", Error::EGRPC_CALL)
|
|
67
|
+
rescue GRPC::BadStatus => e
|
|
68
|
+
Error.new(clean_error_message(e.message), grpc_code_to_one(e.code))
|
|
69
|
+
rescue StandardError => e
|
|
70
|
+
Error.new("#{action}: #{e.message}", Error::EGRPC_CALL)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def clean_error_message(msg)
|
|
76
|
+
cleaned = msg.sub(/\A\d+:/, '').strip
|
|
77
|
+
cleaned.sub(/debug_error_string:.*$/, '').strip
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Maps gRPC status codes to OpenNebula error codes
|
|
81
|
+
def grpc_code_to_one(grpc_code)
|
|
82
|
+
case grpc_code
|
|
83
|
+
when GRPC::Core::StatusCodes::UNAUTHENTICATED
|
|
84
|
+
Error::EAUTHENTICATION
|
|
85
|
+
when GRPC::Core::StatusCodes::PERMISSION_DENIED
|
|
86
|
+
Error::EAUTHORIZATION
|
|
87
|
+
when GRPC::Core::StatusCodes::NOT_FOUND
|
|
88
|
+
Error::ENO_EXISTS
|
|
89
|
+
when GRPC::Core::StatusCodes::INVALID_ARGUMENT
|
|
90
|
+
Error::ERPC_API
|
|
91
|
+
when GRPC::Core::StatusCodes::INTERNAL
|
|
92
|
+
Error::EINTERNAL
|
|
93
|
+
when GRPC::Core::StatusCodes::ALREADY_EXISTS
|
|
94
|
+
Error::EALLOCATE
|
|
95
|
+
when GRPC::Core::StatusCodes::UNIMPLEMENTED
|
|
96
|
+
Error::ENOTDEFINED
|
|
97
|
+
else
|
|
98
|
+
Error::EGRPC_CALL
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
# rubocop:enable Style/Documentation
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
|
2
|
+
# Copyright 2002-2026, OpenNebula Project, OpenNebula Systems #
|
|
3
|
+
# #
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
|
6
|
+
# a copy of the License at #
|
|
7
|
+
# #
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
9
|
+
# #
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
13
|
+
# See the License for the specific language governing permissions and #
|
|
14
|
+
# limitations under the License. #
|
|
15
|
+
#--------------------------------------------------------------------------- #
|
|
16
|
+
|
|
17
|
+
require 'xmlrpc/client'
|
|
18
|
+
require 'bigdecimal'
|
|
19
|
+
require 'stringio'
|
|
20
|
+
require 'openssl'
|
|
21
|
+
require 'opennebula/xml_utils'
|
|
22
|
+
|
|
23
|
+
# rubocop:disable Style/Documentation
|
|
24
|
+
# rubocop:disable Lint/MissingSuper
|
|
25
|
+
module OpenNebula
|
|
26
|
+
|
|
27
|
+
if OpenNebula::OX
|
|
28
|
+
|
|
29
|
+
class OxStreamParser < XMLRPC::XMLParser::AbstractStreamParser
|
|
30
|
+
|
|
31
|
+
def initialize
|
|
32
|
+
@parser_class = OxParser
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class OxParser < Ox::Sax
|
|
36
|
+
|
|
37
|
+
include XMLRPC::XMLParser::StreamParserMixin
|
|
38
|
+
|
|
39
|
+
alias text character
|
|
40
|
+
alias end_element endElement
|
|
41
|
+
alias start_element startElement
|
|
42
|
+
|
|
43
|
+
def parse(str)
|
|
44
|
+
Ox.sax_parse(self,
|
|
45
|
+
StringIO.new(str),
|
|
46
|
+
:symbolize => false,
|
|
47
|
+
:convert_special => true,
|
|
48
|
+
:skip => :skip_none)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
elsif OpenNebula::NOKOGIRI
|
|
55
|
+
class NokogiriStreamParser < XMLRPC::XMLParser::AbstractStreamParser
|
|
56
|
+
|
|
57
|
+
def initialize
|
|
58
|
+
@parser_class = NokogiriParser
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class NokogiriParser < Nokogiri::XML::SAX::Document
|
|
62
|
+
|
|
63
|
+
include XMLRPC::XMLParser::StreamParserMixin
|
|
64
|
+
|
|
65
|
+
alias cdata_block character
|
|
66
|
+
alias characters character
|
|
67
|
+
alias end_element endElement
|
|
68
|
+
alias start_element startElement
|
|
69
|
+
|
|
70
|
+
def parse(str)
|
|
71
|
+
parser = Nokogiri::XML::SAX::Parser.new(self)
|
|
72
|
+
parser.parse(str)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# The openNebula XMLRPC client class, represents the connection with the core
|
|
81
|
+
# and handles the xml-rpc calls.
|
|
82
|
+
class XMLClient
|
|
83
|
+
|
|
84
|
+
begin
|
|
85
|
+
require 'xmlparser'
|
|
86
|
+
XMLPARSER=true
|
|
87
|
+
rescue LoadError
|
|
88
|
+
XMLPARSER=false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Creates a new XMLRPC client object that will be used to call OpenNebula
|
|
92
|
+
# functions.
|
|
93
|
+
#
|
|
94
|
+
# @param [String, nil] secret user credentials ("user:password") or
|
|
95
|
+
# nil to get the credentials from user auth file
|
|
96
|
+
# @param [String, nil] endpoint OpenNebula server endpoint
|
|
97
|
+
# (http://host:2633/RPC2) or nil to get it from the environment
|
|
98
|
+
# variable ONE_XMLRPC or use the default endpoint
|
|
99
|
+
# @param [Hash] options
|
|
100
|
+
# @option params [Integer] :timeout connection timeout in seconds,
|
|
101
|
+
# defaults to 30
|
|
102
|
+
# @option params [String] :http_proxy HTTP proxy string used for
|
|
103
|
+
# connecting to the endpoint; defaults to no proxy
|
|
104
|
+
# @option params [Boolean] :sync Use only one http connection for
|
|
105
|
+
# all calls. It should not be used for multithreaded programs.
|
|
106
|
+
# It's the only mode that can be used with :cert_dir and
|
|
107
|
+
# :disable_ssl_verify
|
|
108
|
+
# @option params [String] :cert_dir Extra directory where to import
|
|
109
|
+
# trusted issuer certificates. Use with :sync = true
|
|
110
|
+
# @option params [String] :disable_ssl_verify Disable SSL certificate
|
|
111
|
+
# verification. Use only for testing and with :sync = true
|
|
112
|
+
#
|
|
113
|
+
# @return [OpenNebula::XMLClient]
|
|
114
|
+
def initialize(secret, endpoint, options = {})
|
|
115
|
+
@one_auth = secret
|
|
116
|
+
@one_endpoint = endpoint
|
|
117
|
+
|
|
118
|
+
@async = !options[:sync]
|
|
119
|
+
|
|
120
|
+
http_proxy = options[:http_proxy]
|
|
121
|
+
timeout = options[:timeout] || ENV['ONE_XMLRPC_TIMEOUT']&.to_i
|
|
122
|
+
|
|
123
|
+
@server = XMLRPC::Client.new2(@one_endpoint, http_proxy, timeout)
|
|
124
|
+
@server.http_header_extra = { 'accept-encoding' => 'identity' }
|
|
125
|
+
|
|
126
|
+
http = @server.instance_variable_get('@http')
|
|
127
|
+
|
|
128
|
+
if options[:cert_dir] || ENV['ONE_CERT_DIR']
|
|
129
|
+
raise "SSL options don't work in async mode" if @async
|
|
130
|
+
|
|
131
|
+
cert_dir = options[:cert_dir] || ENV['ONE_CERT_DIR']
|
|
132
|
+
cert_files = Dir["#{cert_dir}/*"]
|
|
133
|
+
|
|
134
|
+
cert_store = OpenSSL::X509::Store.new
|
|
135
|
+
cert_store.set_default_paths
|
|
136
|
+
cert_files.each {|cert| cert_store.add_file(cert) }
|
|
137
|
+
|
|
138
|
+
http.cert_store = cert_store
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
if options[:disable_ssl_verify] || ENV['ONE_DISABLE_SSL_VERIFY']
|
|
142
|
+
raise "SSL options don't work in async mode" if @async
|
|
143
|
+
|
|
144
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
if defined?(OxStreamParser)
|
|
148
|
+
@server.set_parser(OxStreamParser.new)
|
|
149
|
+
elsif OpenNebula::NOKOGIRI
|
|
150
|
+
@server.set_parser(NokogiriStreamParser.new)
|
|
151
|
+
elsif XMLPARSER
|
|
152
|
+
@server.set_parser(XMLRPC::XMLParser::XMLStreamParser.new)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def call(action, *args)
|
|
157
|
+
begin
|
|
158
|
+
if @async
|
|
159
|
+
response = @server.call_async("one.#{action}", @one_auth, *args)
|
|
160
|
+
else
|
|
161
|
+
response = @server.call("one.#{action}", @one_auth, *args)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
if response[0] == false
|
|
165
|
+
Error.new(response[1], response[2])
|
|
166
|
+
else
|
|
167
|
+
response[1] # response[1..-1]
|
|
168
|
+
end
|
|
169
|
+
rescue StandardError => e
|
|
170
|
+
Error.new(e.message, Error::EXML_RPC_CALL)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
end
|
|
177
|
+
# rubocop:enable Style/Documentation
|
|
178
|
+
# rubocop:enable Lint/MissingSuper
|
data/lib/opennebula/version.rb
CHANGED
|
@@ -348,7 +348,6 @@ module OpenNebula
|
|
|
348
348
|
#
|
|
349
349
|
# @return [String] the xml representing the accounting data
|
|
350
350
|
def accounting_xml(filter_flag=INFO_ALL, options={})
|
|
351
|
-
acct_hash = Hash.new
|
|
352
351
|
xml_str = "<HISTORY_RECORDS>\n"
|
|
353
352
|
|
|
354
353
|
rc = build_accounting(filter_flag, options) do |history|
|
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.2.
|
|
4
|
+
version: 7.2.1
|
|
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-05-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: nokogiri
|
|
@@ -185,6 +185,9 @@ files:
|
|
|
185
185
|
- lib/opennebula/image_pool.rb
|
|
186
186
|
- lib/opennebula/ldap_auth.rb
|
|
187
187
|
- lib/opennebula/ldap_auth_spec.rb
|
|
188
|
+
- lib/opennebula/lib/client.rb
|
|
189
|
+
- lib/opennebula/lib/grpc_client.rb
|
|
190
|
+
- lib/opennebula/lib/xml_client.rb
|
|
188
191
|
- lib/opennebula/lockable_ext.rb
|
|
189
192
|
- lib/opennebula/marketplace.rb
|
|
190
193
|
- lib/opennebula/marketplace_pool.rb
|