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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ba213cbf9c61bf639e606a86a5496dc10523a36845bab21e78dc69e096e4a6a
4
- data.tar.gz: 6c56a7baf3e61745b7ab9d2959dc0cc21d04aa717e69153e21e4c4b07a57c0f9
3
+ metadata.gz: ec857d82d9122d895b79906537bc2bdd190c4a8b5ce0af34293fb944b7e222e4
4
+ data.tar.gz: 07f7b9481eb44a0d18d65d81381c65024492d22cba724378f8f598ce97ee5bdc
5
5
  SHA512:
6
- metadata.gz: 6946c2f94864b1101171a7a60d67afe95956777b031f87699601fc3165a410949e1e9b3470c21bb04375ce151a773561731e8275b53fae73174ef6b5365f1e63
7
- data.tar.gz: ab5eda8064f4133f6e3751a10923a21f3000903e63bce981d652cd54fd9c15d9a3d8fbefa15a98eb0235008d27898199ee973ecef541c10b1d80b571d036b14f
6
+ metadata.gz: 4b23c2de26bd07cb1d8949921ee385cf4746b248028197bbf0e14f3c23f96f6d577e2d76c3db4cf52190ba1542c4b1da606a5b641f76df9d47e5d0fd7cea52df
7
+ data.tar.gz: 7eb669f3a42846376ed7e8423923e86e32767774be0bf854d5797cde069ae8dc5544a5c4a9ce0c9ca2a2cf0664841bd8ce22f38c00658aa13d963d3f18cc99a3
@@ -51,7 +51,7 @@ end
51
51
  module CloudClient
52
52
 
53
53
  # OpenNebula version
54
- VERSION = '7.2.0'
54
+ VERSION = '7.2.1'
55
55
 
56
56
  # #########################################################################
57
57
  # Default location for the authentication file
@@ -63,7 +63,7 @@ module OpenNebula
63
63
  # Returns true if the object returned by a method of the OpenNebula
64
64
  # library is an Error
65
65
  def self.is_error?(value)
66
- value.class==OpenNebula::Error
66
+ value.is_a?(OpenNebula::Error)
67
67
  end
68
68
 
69
69
  end
@@ -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
@@ -17,6 +17,6 @@
17
17
  module OpenNebula
18
18
 
19
19
  # OpenNebula version
20
- VERSION = '7.2.0'
20
+ VERSION = '7.2.1'
21
21
 
22
22
  end
@@ -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.0
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-03-30 00:00:00.000000000 Z
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