opennebula-cli 5.12.13 → 5.13.80.pre
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 +5 -5
- data/bin/oneacct +5 -14
- data/bin/oneacl +4 -15
- data/bin/onecluster +6 -17
- data/bin/onedatastore +6 -17
- data/bin/oneflow +81 -23
- data/bin/oneflow-template +51 -27
- data/bin/onegroup +6 -17
- data/bin/onehook +6 -17
- data/bin/onehost +4 -15
- data/bin/oneimage +95 -18
- data/bin/onemarket +6 -17
- data/bin/onemarketapp +113 -20
- data/bin/onesecgroup +9 -17
- data/bin/oneshowback +14 -20
- data/bin/onetemplate +8 -18
- data/bin/oneuser +26 -17
- data/bin/onevcenter +6 -28
- data/bin/onevdc +6 -17
- data/bin/onevm +142 -21
- data/bin/onevmgroup +9 -17
- data/bin/onevnet +4 -15
- data/bin/onevntemplate +7 -17
- data/bin/onevrouter +6 -17
- data/bin/onezone +6 -17
- data/lib/cli_helper.rb +7 -10
- data/lib/command_parser.rb +1 -1
- data/lib/one_helper/oneacct_helper.rb +9 -22
- data/lib/one_helper/oneacl_helper.rb +1 -1
- data/lib/one_helper/onecluster_helper.rb +1 -1
- data/lib/one_helper/onedatastore_helper.rb +11 -1
- data/lib/one_helper/oneflow_helper.rb +20 -5
- data/lib/one_helper/oneflowtemplate_helper.rb +28 -2
- data/lib/one_helper/onegroup_helper.rb +1 -1
- data/lib/one_helper/onehook_helper.rb +1 -1
- data/lib/one_helper/onehost_helper.rb +1 -5
- data/lib/one_helper/oneimage_helper.rb +7 -7
- data/lib/one_helper/onemarket_helper.rb +1 -1
- data/lib/one_helper/onemarketapp_helper.rb +494 -96
- data/lib/one_helper/onequota_helper.rb +1 -1
- data/lib/one_helper/onesecgroup_helper.rb +1 -1
- data/lib/one_helper/onetemplate_helper.rb +12 -1
- data/lib/one_helper/oneuser_helper.rb +11 -3
- data/lib/one_helper/onevcenter_helper.rb +176 -146
- data/lib/one_helper/onevdc_helper.rb +1 -1
- data/lib/one_helper/onevm_helper.rb +9 -9
- data/lib/one_helper/onevmgroup_helper.rb +1 -1
- data/lib/one_helper/onevnet_helper.rb +1 -1
- data/lib/one_helper/onevntemplate_helper.rb +1 -1
- data/lib/one_helper/onevrouter_helper.rb +1 -20
- data/lib/one_helper/onezone_helper.rb +12 -1
- data/lib/one_helper.rb +398 -37
- data/share/schemas/xsd/acct.xsd +179 -0
- data/share/schemas/xsd/acl_pool.xsd +22 -0
- data/share/schemas/xsd/api_info.xsd +43 -0
- data/share/schemas/xsd/cluster.xsd +34 -0
- data/share/schemas/xsd/cluster_pool.xsd +12 -0
- data/share/schemas/xsd/datastore.xsd +67 -0
- data/share/schemas/xsd/datastore_pool.xsd +12 -0
- data/share/schemas/xsd/document.xsd +42 -0
- data/share/schemas/xsd/document_pool.xsd +12 -0
- data/share/schemas/xsd/group.xsd +179 -0
- data/share/schemas/xsd/group_pool.xsd +194 -0
- data/share/schemas/xsd/hook.xsd +59 -0
- data/share/schemas/xsd/hook_message_api.xsd +14 -0
- data/share/schemas/xsd/hook_message_retry.xsd +12 -0
- data/share/schemas/xsd/hook_message_state.xsd +25 -0
- data/share/schemas/xsd/hook_pool.xsd +12 -0
- data/share/schemas/xsd/host.xsd +164 -0
- data/share/schemas/xsd/host_pool.xsd +12 -0
- data/share/schemas/xsd/image.xsd +123 -0
- data/share/schemas/xsd/image_pool.xsd +12 -0
- data/share/schemas/xsd/index.xsd +49 -0
- data/share/schemas/xsd/marketplace.xsd +44 -0
- data/share/schemas/xsd/marketplace_pool.xsd +12 -0
- data/share/schemas/xsd/marketplaceapp.xsd +56 -0
- data/share/schemas/xsd/marketplaceapp_pool.xsd +12 -0
- data/share/schemas/xsd/opennebula_configuration.xsd +412 -0
- data/share/schemas/xsd/raftstatus.xsd +18 -0
- data/share/schemas/xsd/security_group.xsd +74 -0
- data/share/schemas/xsd/security_group_pool.xsd +12 -0
- data/share/schemas/xsd/showback.xsd +29 -0
- data/share/schemas/xsd/user.xsd +186 -0
- data/share/schemas/xsd/user_pool.xsd +201 -0
- data/share/schemas/xsd/vdc.xsd +76 -0
- data/share/schemas/xsd/vdc_pool.xsd +12 -0
- data/share/schemas/xsd/vm.xsd +251 -0
- data/share/schemas/xsd/vm_group.xsd +59 -0
- data/share/schemas/xsd/vm_group_pool.xsd +12 -0
- data/share/schemas/xsd/vm_pool.xsd +114 -0
- data/share/schemas/xsd/vmtemplate.xsd +52 -0
- data/share/schemas/xsd/vmtemplate_pool.xsd +12 -0
- data/share/schemas/xsd/vnet.xsd +137 -0
- data/share/schemas/xsd/vnet_pool.xsd +85 -0
- data/share/schemas/xsd/vntemplate.xsd +50 -0
- data/share/schemas/xsd/vntemplate_pool.xsd +12 -0
- data/share/schemas/xsd/vrouter.xsd +49 -0
- data/share/schemas/xsd/vrouter_pool.xsd +12 -0
- data/share/schemas/xsd/zone.xsd +40 -0
- data/share/schemas/xsd/zone_pool.xsd +36 -0
- metadata +92 -30
- data/lib/one_helper/oneprovision_helper.rb +0 -362
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -15,100 +15,118 @@
|
|
|
15
15
|
#--------------------------------------------------------------------------- #
|
|
16
16
|
|
|
17
17
|
require 'one_helper'
|
|
18
|
+
require 'opennebula/marketplaceapp_ext'
|
|
19
|
+
require 'opennebula/template_ext'
|
|
20
|
+
require 'opennebula/virtual_machine_ext'
|
|
21
|
+
require 'opennebula/flow/service_template_ext'
|
|
18
22
|
|
|
23
|
+
require 'securerandom'
|
|
24
|
+
|
|
25
|
+
# OneMarketApp Command Helper
|
|
19
26
|
class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
|
27
|
+
|
|
20
28
|
TEMPLATE_OPTIONS=[
|
|
21
29
|
{
|
|
22
|
-
:name =>
|
|
23
|
-
:large =>
|
|
30
|
+
:name => 'name',
|
|
31
|
+
:large => '--name name',
|
|
24
32
|
:format => String,
|
|
25
|
-
:description =>
|
|
33
|
+
:description => 'Name of the new MarketPlaceApp'
|
|
26
34
|
},
|
|
27
35
|
{
|
|
28
|
-
:name =>
|
|
29
|
-
:large =>
|
|
36
|
+
:name => 'description',
|
|
37
|
+
:large => '--description description',
|
|
30
38
|
:format => String,
|
|
31
|
-
:description =>
|
|
39
|
+
:description => 'Description for the new MarketPlaceApp'
|
|
32
40
|
},
|
|
33
41
|
{
|
|
34
|
-
:name =>
|
|
35
|
-
:large =>
|
|
36
|
-
:description =>
|
|
42
|
+
:name => 'image',
|
|
43
|
+
:large => '--image id|name',
|
|
44
|
+
:description => 'Selects the image',
|
|
37
45
|
:format => String,
|
|
38
|
-
:template_key =>
|
|
39
|
-
:proc => lambda {
|
|
40
|
-
OpenNebulaHelper.rname_to_id(o,
|
|
46
|
+
:template_key => 'origin_id',
|
|
47
|
+
:proc => lambda {|o, _options|
|
|
48
|
+
OpenNebulaHelper.rname_to_id(o, 'IMAGE')
|
|
41
49
|
}
|
|
42
50
|
},
|
|
43
51
|
OpenNebulaHelper::DRY
|
|
44
52
|
]
|
|
45
53
|
|
|
46
54
|
VMNAME = {
|
|
47
|
-
:name =>
|
|
48
|
-
:large =>
|
|
49
|
-
:description =>
|
|
55
|
+
:name => 'vmname',
|
|
56
|
+
:large => '--vmname name',
|
|
57
|
+
:description => 'Selects the name for the new VM Template, ' \
|
|
58
|
+
'if the App contains one',
|
|
50
59
|
:format => String
|
|
51
60
|
}
|
|
52
61
|
|
|
62
|
+
# Available market place mads to import apps on them
|
|
63
|
+
MARKETS = %w[http s3]
|
|
64
|
+
|
|
53
65
|
def self.rname
|
|
54
|
-
|
|
66
|
+
'MARKETPLACEAPP'
|
|
55
67
|
end
|
|
56
68
|
|
|
57
69
|
def self.conf_file
|
|
58
|
-
|
|
70
|
+
'onemarketapp.yaml'
|
|
59
71
|
end
|
|
60
72
|
|
|
61
73
|
def self.state_to_str(id)
|
|
62
74
|
id = id.to_i
|
|
63
75
|
state_str = MarketPlaceApp::MARKETPLACEAPP_STATES[id]
|
|
64
|
-
|
|
76
|
+
MarketPlaceApp::SHORT_MARKETPLACEAPP_STATES[state_str]
|
|
65
77
|
end
|
|
66
78
|
|
|
67
|
-
def format_pool(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
d[
|
|
79
|
+
def format_pool(_options)
|
|
80
|
+
CLIHelper::ShowTable.new(self.class.table_conf, self) do
|
|
81
|
+
column :ID,
|
|
82
|
+
'ONE identifier for the marketplace app',
|
|
83
|
+
:size=>4 do |d|
|
|
84
|
+
d['ID']
|
|
73
85
|
end
|
|
74
86
|
|
|
75
|
-
column :NAME,
|
|
76
|
-
d[
|
|
87
|
+
column :NAME, 'Name of the marketplace app', :left, :size=>25 do |d|
|
|
88
|
+
d['NAME']
|
|
77
89
|
end
|
|
78
90
|
|
|
79
|
-
column :VERSION,
|
|
80
|
-
d[
|
|
91
|
+
column :VERSION, 'Version of the app', :size=>10 do |d|
|
|
92
|
+
d['VERSION']
|
|
81
93
|
end
|
|
82
94
|
|
|
83
|
-
column :SIZE,
|
|
95
|
+
column :SIZE, 'App size', :size =>5 do |d|
|
|
84
96
|
OpenNebulaHelper.unit_to_str(d['SIZE'].to_i, {}, 'M')
|
|
85
97
|
end
|
|
86
98
|
|
|
87
|
-
column :STAT,
|
|
88
|
-
OneMarketPlaceAppHelper.state_to_str(d[
|
|
99
|
+
column :STAT, 'State of the app', :size=>4 do |d|
|
|
100
|
+
OneMarketPlaceAppHelper.state_to_str(d['STATE'])
|
|
89
101
|
end
|
|
90
102
|
|
|
91
|
-
column :REGTIME,
|
|
92
|
-
Time.at(d['REGTIME'].to_i).strftime(
|
|
103
|
+
column :REGTIME, 'Registration time of the app', :size=>8 do |d|
|
|
104
|
+
Time.at(d['REGTIME'].to_i).strftime('%D')
|
|
93
105
|
end
|
|
94
106
|
|
|
95
|
-
column :TYPE,
|
|
96
|
-
type = MarketPlaceApp::MARKETPLACEAPP_TYPES[d[
|
|
107
|
+
column :TYPE, 'Marketplace app type', :size=>4 do |d|
|
|
108
|
+
type = MarketPlaceApp::MARKETPLACEAPP_TYPES[d['TYPE'].to_i]
|
|
97
109
|
MarketPlaceApp::SHORT_MARKETPLACEAPP_TYPES[type]
|
|
98
110
|
end
|
|
99
111
|
|
|
100
|
-
column :MARKET,
|
|
101
|
-
d[
|
|
112
|
+
column :MARKET, 'Name of the MarketPlace', :left, :size=>20 do |d|
|
|
113
|
+
d['MARKETPLACE']
|
|
102
114
|
end
|
|
103
115
|
|
|
104
|
-
column :ZONE,
|
|
105
|
-
d[
|
|
116
|
+
column :ZONE, 'Zone ID', :size=>4 do |d|
|
|
117
|
+
d['ZONE_ID']
|
|
106
118
|
end
|
|
107
119
|
|
|
108
|
-
default :ID
|
|
120
|
+
default :ID,
|
|
121
|
+
:NAME,
|
|
122
|
+
:VERSION,
|
|
123
|
+
:SIZE,
|
|
124
|
+
:STAT,
|
|
125
|
+
:TYPE,
|
|
126
|
+
:REGTIME,
|
|
127
|
+
:MARKET,
|
|
128
|
+
:ZONE
|
|
109
129
|
end
|
|
110
|
-
|
|
111
|
-
table
|
|
112
130
|
end
|
|
113
131
|
|
|
114
132
|
def self.create_template_options_used?(options)
|
|
@@ -123,9 +141,236 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
|
|
123
141
|
(template_options-options.keys)!=template_options
|
|
124
142
|
end
|
|
125
143
|
|
|
144
|
+
# Import object into marketplace
|
|
145
|
+
#
|
|
146
|
+
# @param object [String] Object ID or name
|
|
147
|
+
# @param o_class [Class] Object class
|
|
148
|
+
def import(object, o_class)
|
|
149
|
+
id = get_obj_id(object, o_class)
|
|
150
|
+
|
|
151
|
+
if OpenNebula.is_error?(id)
|
|
152
|
+
STDERR.puts id.message
|
|
153
|
+
exit(-1)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
rc = yield(id) if block_given?
|
|
157
|
+
|
|
158
|
+
if OpenNebula.is_error?(rc)
|
|
159
|
+
STDERR.puts rc.message
|
|
160
|
+
exit(-1)
|
|
161
|
+
elsif rc[0] == -1
|
|
162
|
+
STDERR.puts rc[1]
|
|
163
|
+
exit(-1)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
0
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Import service template into marketplace
|
|
170
|
+
#
|
|
171
|
+
# @param id [Integer] Service Template ID
|
|
172
|
+
# @param options [Hash] User CLI options
|
|
173
|
+
#
|
|
174
|
+
# @return [Error code, error message] 0 if everything was correct
|
|
175
|
+
# 1 otherwhise
|
|
176
|
+
def import_service_template(id, options)
|
|
177
|
+
require 'json'
|
|
178
|
+
|
|
179
|
+
pool = private_markets
|
|
180
|
+
|
|
181
|
+
return pool if OpenNebula.is_error?(pool)
|
|
182
|
+
|
|
183
|
+
s_template = ServiceTemplate.new_with_id(id, @client)
|
|
184
|
+
rc = s_template.info
|
|
185
|
+
|
|
186
|
+
return rc if OpenNebula.is_error?(rc)
|
|
187
|
+
|
|
188
|
+
body = JSON.parse(s_template.to_json)['DOCUMENT']['TEMPLATE']['BODY']
|
|
189
|
+
import_all = options[:yes] || options[:no]
|
|
190
|
+
|
|
191
|
+
while import_all != 'no' && import_all != 'yes'
|
|
192
|
+
print 'Do you want to import images too? (yes/no, default=yes): '
|
|
193
|
+
import_all = STDIN.readline.chop.downcase
|
|
194
|
+
|
|
195
|
+
if import_all.empty?
|
|
196
|
+
puts 'yes'
|
|
197
|
+
import_all = 'yes'
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
main_market = options[:market]
|
|
202
|
+
|
|
203
|
+
# Read marketplace where import the service template
|
|
204
|
+
# It can only be a private marketplace
|
|
205
|
+
unless main_market
|
|
206
|
+
puts
|
|
207
|
+
puts 'Available Marketplaces (please enter ID)'
|
|
208
|
+
pool.each {|market| puts "- #{market['ID']}: #{market['NAME']}" }
|
|
209
|
+
puts
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
default_mp = pool.first['ID'].to_i
|
|
213
|
+
|
|
214
|
+
# Keep asking while user selects an incorrect marketplace
|
|
215
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, main_market)
|
|
216
|
+
print 'Where do you want to import the Service template? ' \
|
|
217
|
+
"(default=#{default_mp})"
|
|
218
|
+
main_market = STDIN.readline.chop
|
|
219
|
+
|
|
220
|
+
if main_market.empty?
|
|
221
|
+
puts default_mp
|
|
222
|
+
main_market = default_mp
|
|
223
|
+
else
|
|
224
|
+
main_market = main_market.to_i
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
markets = import_service_template_roles(import_all,
|
|
229
|
+
body,
|
|
230
|
+
pool,
|
|
231
|
+
options[:market])
|
|
232
|
+
ids = []
|
|
233
|
+
|
|
234
|
+
# Create roles apps
|
|
235
|
+
if import_all == 'yes'
|
|
236
|
+
rc = create_apps(markets, import_all)
|
|
237
|
+
ids = rc[1]
|
|
238
|
+
|
|
239
|
+
return [-1, rc[0]] unless rc[0].empty?
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Create service template app
|
|
243
|
+
s_template.extend(ServiceTemplateExt)
|
|
244
|
+
|
|
245
|
+
rc = s_template.mp_import(markets, main_market, options[:vmname])
|
|
246
|
+
|
|
247
|
+
if rc[0] == -1
|
|
248
|
+
rc
|
|
249
|
+
else
|
|
250
|
+
ids.each {|i| puts "ID: #{i}" }
|
|
251
|
+
puts "ID: #{rc[1]}"
|
|
252
|
+
[0, nil]
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Import VM Template into marketplace
|
|
257
|
+
#
|
|
258
|
+
# @param id [Integer] VM Template ID
|
|
259
|
+
# @param options [Hash] User CLI options
|
|
260
|
+
#
|
|
261
|
+
# @return [Error code, error message] 0 if everything was correct
|
|
262
|
+
# 1 otherwhise
|
|
263
|
+
def import_vm_template(id, options)
|
|
264
|
+
pool = private_markets
|
|
265
|
+
|
|
266
|
+
return pool if OpenNebula.is_error?(pool)
|
|
267
|
+
|
|
268
|
+
template = Template.new_with_id(id, @client)
|
|
269
|
+
rc = template.info
|
|
270
|
+
|
|
271
|
+
return rc if OpenNebula.is_error?(rc)
|
|
272
|
+
|
|
273
|
+
import_all = options[:yes] || options[:no]
|
|
274
|
+
|
|
275
|
+
while import_all != 'no' && import_all != 'yes'
|
|
276
|
+
print 'Do you want to import images too? (yes/no, default=yes): '
|
|
277
|
+
import_all = STDIN.readline.chop.downcase
|
|
278
|
+
|
|
279
|
+
if import_all.empty?
|
|
280
|
+
puts 'yes'
|
|
281
|
+
import_all = 'yes'
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
main_market = options[:market]
|
|
286
|
+
|
|
287
|
+
# Read marketplace where import the VM template
|
|
288
|
+
# It can only be a private marketplace
|
|
289
|
+
unless main_market
|
|
290
|
+
puts
|
|
291
|
+
puts 'Available Marketplaces (please enter ID)'
|
|
292
|
+
pool.each {|market| puts "- #{market['ID']}: #{market['NAME']}" }
|
|
293
|
+
puts
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
default_mp = pool.first['ID'].to_i
|
|
297
|
+
|
|
298
|
+
# Keep asking while user selects an incorrect marketplace
|
|
299
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, main_market)
|
|
300
|
+
print 'Where do you want to import the VM template? ' \
|
|
301
|
+
"(default=#{default_mp})"
|
|
302
|
+
main_market = STDIN.readline.chop
|
|
303
|
+
|
|
304
|
+
if main_market.empty?
|
|
305
|
+
puts default_mp
|
|
306
|
+
main_market = default_mp
|
|
307
|
+
else
|
|
308
|
+
main_market = main_market.to_i
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Templates import information
|
|
313
|
+
#
|
|
314
|
+
# template_id => :market => marketplace ID to import it
|
|
315
|
+
# :template => ONE Template information
|
|
316
|
+
# :name => generated name for the template
|
|
317
|
+
markets = {}
|
|
318
|
+
markets[template['ID']] = {}
|
|
319
|
+
markets[template['ID']][:market] = main_market
|
|
320
|
+
markets[template['ID']][:template] = template
|
|
321
|
+
|
|
322
|
+
rc = create_apps(markets, import_all, options[:vmname])
|
|
323
|
+
|
|
324
|
+
if rc[0] == -1
|
|
325
|
+
rc
|
|
326
|
+
else
|
|
327
|
+
rc[1].each {|i| puts "ID: #{i}" }
|
|
328
|
+
[0, nil]
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# Save VM as template to be able to import it
|
|
333
|
+
#
|
|
334
|
+
# @param id [Integer] VM ID
|
|
335
|
+
#
|
|
336
|
+
# @return [Integer] New template ID
|
|
337
|
+
def save_as_template(id)
|
|
338
|
+
vm = VirtualMachine.new_with_id(id, @client)
|
|
339
|
+
rc = vm.info
|
|
340
|
+
|
|
341
|
+
return rc if OpenNebula.is_error?(rc)
|
|
342
|
+
|
|
343
|
+
vm.extend(VirtualMachineExt)
|
|
344
|
+
|
|
345
|
+
vm.save_as_template("#{vm['NAME']}-saved", 'App to import')
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Get object ID from name
|
|
349
|
+
#
|
|
350
|
+
# @param id [String] ID or NAME
|
|
351
|
+
# @param obj [OpenNebula::Class] OpenNebula pool class
|
|
352
|
+
#
|
|
353
|
+
# @return [Integer] Object ID
|
|
354
|
+
def get_obj_id(id, obj)
|
|
355
|
+
if (id.is_a? Integer) || id.match(/^\d+$/)
|
|
356
|
+
id.to_i
|
|
357
|
+
else
|
|
358
|
+
pool = obj.new(@client)
|
|
359
|
+
rc = pool.info_all
|
|
360
|
+
|
|
361
|
+
return rc if OpenNebula.is_error?(rc)
|
|
362
|
+
|
|
363
|
+
rc = pool.find {|v| v['NAME'] == id }
|
|
364
|
+
|
|
365
|
+
return Error.new("Object `#{id}` not found") unless rc
|
|
366
|
+
|
|
367
|
+
rc['ID'].to_i
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
126
371
|
private
|
|
127
372
|
|
|
128
|
-
def factory(id=nil)
|
|
373
|
+
def factory(id = nil)
|
|
129
374
|
if id
|
|
130
375
|
OpenNebula::MarketPlaceApp.new_with_id(id, @client)
|
|
131
376
|
else
|
|
@@ -134,91 +379,244 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
|
|
134
379
|
end
|
|
135
380
|
end
|
|
136
381
|
|
|
137
|
-
def factory_pool(user_flag
|
|
382
|
+
def factory_pool(user_flag = -2)
|
|
138
383
|
OpenNebula::MarketPlaceAppPool.new(@client, user_flag)
|
|
139
384
|
end
|
|
140
385
|
|
|
141
|
-
def format_resource(app,
|
|
142
|
-
str=
|
|
143
|
-
str_h1=
|
|
144
|
-
|
|
145
|
-
CLIHelper.print_header(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
puts str
|
|
149
|
-
puts str
|
|
150
|
-
puts str
|
|
151
|
-
puts str
|
|
152
|
-
puts str
|
|
153
|
-
puts str
|
|
386
|
+
def format_resource(app, _options = {})
|
|
387
|
+
str='%-15s: %-20s'
|
|
388
|
+
str_h1='%-80s'
|
|
389
|
+
|
|
390
|
+
CLIHelper.print_header(
|
|
391
|
+
str_h1 % "MARKETPLACE APP #{app['ID']} INFORMATION"
|
|
392
|
+
)
|
|
393
|
+
puts format(str, 'ID', app.id.to_s)
|
|
394
|
+
puts format(str, 'NAME', app.name)
|
|
395
|
+
puts format(str, 'TYPE', app.type_str)
|
|
396
|
+
puts format(str, 'USER', app['UNAME'])
|
|
397
|
+
puts format(str, 'GROUP', app['GNAME'])
|
|
398
|
+
puts format(str, 'MARKETPLACE', app['MARKETPLACE'])
|
|
399
|
+
puts format(str,
|
|
400
|
+
'STATE',
|
|
401
|
+
OneMarketPlaceAppHelper.state_to_str(app['STATE']))
|
|
402
|
+
puts format(str,
|
|
403
|
+
'LOCK',
|
|
404
|
+
OpenNebulaHelper.level_lock_to_str(app['LOCK/LOCKED']))
|
|
154
405
|
|
|
155
406
|
puts
|
|
156
407
|
|
|
157
|
-
CLIHelper.print_header(str_h1 %
|
|
408
|
+
CLIHelper.print_header(str_h1 % 'PERMISSIONS', false)
|
|
158
409
|
|
|
159
|
-
[
|
|
160
|
-
mask =
|
|
161
|
-
mask[0] =
|
|
162
|
-
mask[1] =
|
|
163
|
-
mask[2] =
|
|
410
|
+
%w[OWNER GROUP OTHER].each do |e|
|
|
411
|
+
mask = '---'
|
|
412
|
+
mask[0] = 'u' if app["PERMISSIONS/#{e}_U"] == '1'
|
|
413
|
+
mask[1] = 'm' if app["PERMISSIONS/#{e}_M"] == '1'
|
|
414
|
+
mask[2] = 'a' if app["PERMISSIONS/#{e}_A"] == '1'
|
|
164
415
|
|
|
165
|
-
puts str
|
|
166
|
-
|
|
416
|
+
puts format(str, e, mask)
|
|
417
|
+
end
|
|
167
418
|
puts
|
|
168
419
|
|
|
169
|
-
CLIHelper.print_header(str_h1 %
|
|
170
|
-
|
|
171
|
-
puts str
|
|
172
|
-
puts str
|
|
173
|
-
puts str
|
|
174
|
-
puts str
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
puts str
|
|
178
|
-
puts str
|
|
179
|
-
puts str
|
|
420
|
+
CLIHelper.print_header(str_h1 % 'DETAILS', false)
|
|
421
|
+
|
|
422
|
+
puts format(str, 'SOURCE', app['SOURCE'])
|
|
423
|
+
puts format(str, 'MD5', app['MD5'])
|
|
424
|
+
puts format(str, 'PUBLISHER', app['PUBLISHER'])
|
|
425
|
+
puts format(str,
|
|
426
|
+
'REGISTER TIME',
|
|
427
|
+
Time.at(app['REGTIME'].to_i).strftime('%c'))
|
|
428
|
+
puts format(str, 'VERSION', app['VERSION'])
|
|
429
|
+
puts format(str, 'DESCRIPTION', app['DESCRIPTION'])
|
|
430
|
+
puts format(str,
|
|
431
|
+
'SIZE',
|
|
432
|
+
OpenNebulaHelper.unit_to_str(app['SIZE'].to_i, {}, 'M'))
|
|
433
|
+
puts format(str, 'ORIGIN_ID', app['ORIGIN_ID'])
|
|
434
|
+
puts format(str, 'FORMAT', app['FORMAT'])
|
|
180
435
|
|
|
181
436
|
puts
|
|
182
437
|
|
|
183
|
-
CLIHelper.print_header(str_h1 %
|
|
438
|
+
CLIHelper.print_header(str_h1 % 'IMPORT TEMPLATE', false)
|
|
184
439
|
|
|
185
440
|
puts Base64.decode64(app['APPTEMPLATE64'])
|
|
186
441
|
|
|
187
442
|
puts
|
|
188
443
|
|
|
189
|
-
CLIHelper.print_header(str_h1 %
|
|
444
|
+
CLIHelper.print_header(str_h1 % 'MARKETPLACE APP TEMPLATE', false)
|
|
190
445
|
puts app.template_str
|
|
191
446
|
|
|
192
447
|
puts
|
|
193
448
|
end
|
|
194
449
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
450
|
+
class << self
|
|
451
|
+
|
|
452
|
+
def create_variables(options, name)
|
|
453
|
+
names = [name].flatten
|
|
454
|
+
t = ''
|
|
455
|
+
|
|
456
|
+
names.each do |n|
|
|
457
|
+
next unless options[n]
|
|
458
|
+
|
|
459
|
+
t << "#{n.to_s.upcase}=\"#{options[n]}\"\n"
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
t
|
|
200
463
|
end
|
|
201
464
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
t<<"#{n.to_s.upcase}=\"#{options[n]}\"\n"
|
|
465
|
+
def create_datastore_template(options)
|
|
466
|
+
template_options = TEMPLATE_OPTIONS.map do |o|
|
|
467
|
+
o[:name].to_sym
|
|
206
468
|
end
|
|
469
|
+
|
|
470
|
+
template = create_variables(options,
|
|
471
|
+
template_options-[:dry, :image])
|
|
472
|
+
|
|
473
|
+
template << "ORIGIN_ID=#{options[:image]}\n" if options[:image]
|
|
474
|
+
template << "TYPE=image\n"
|
|
475
|
+
|
|
476
|
+
[0, template]
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
# Check if marketplace exists
|
|
480
|
+
#
|
|
481
|
+
# @param pool [MarketPlacePool] Marketplaces pool
|
|
482
|
+
# @param market [String] ID to check
|
|
483
|
+
#
|
|
484
|
+
# @return [Boolean] True if exists, false otherwise
|
|
485
|
+
def market_exist?(pool, market)
|
|
486
|
+
!pool.select {|v| v['ID'].to_i == market }.empty?
|
|
207
487
|
end
|
|
208
488
|
|
|
209
|
-
t
|
|
210
489
|
end
|
|
211
490
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
491
|
+
# Get private marketplace to import templates
|
|
492
|
+
#
|
|
493
|
+
# @return [OpenNebula::Pool] Marketplace pool or error if any
|
|
494
|
+
def private_markets
|
|
495
|
+
pool = MarketPlacePool.new(@client)
|
|
496
|
+
rc = pool.info
|
|
497
|
+
|
|
498
|
+
return rc if OpenNebula.is_error?(rc)
|
|
499
|
+
|
|
500
|
+
# Get private marketplaces
|
|
501
|
+
pool = pool.select {|market| MARKETS.include?(market['MARKET_MAD']) }
|
|
502
|
+
pool = pool.sort_by {|market| market['ID'].to_i }
|
|
503
|
+
|
|
504
|
+
if pool.empty?
|
|
505
|
+
return Error.new("There are no #{MARKETS.join('/')} marketplaces")
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
pool
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
# Get roles information when importing a service template into marketplace
|
|
512
|
+
#
|
|
513
|
+
# @param import_all [String] yes to import VM templates too, no otherwise
|
|
514
|
+
# @param body [Hash] Sevice Template information
|
|
515
|
+
# @param pool [Array] Marketplace pool
|
|
516
|
+
# @param market [Integer] Marketplace to import
|
|
517
|
+
#
|
|
518
|
+
# @return [Hash] Roles templates and marketplaces to import them
|
|
519
|
+
def import_service_template_roles(import_all, body, pool, market)
|
|
520
|
+
# Templates import information
|
|
521
|
+
#
|
|
522
|
+
# template_id => :market => marketplace ID to import it
|
|
523
|
+
# :template => ONE Template information
|
|
524
|
+
# :name => generated name for the template
|
|
525
|
+
markets = {}
|
|
526
|
+
default_mp = pool.first['ID'].to_i
|
|
527
|
+
|
|
528
|
+
if import_all == 'yes'
|
|
529
|
+
# Read marketplace where import each different VM template
|
|
530
|
+
# It can only be a private marketplace
|
|
531
|
+
unless market
|
|
532
|
+
puts
|
|
533
|
+
puts 'Available Marketplaces for roles (please enter ID)'
|
|
534
|
+
pool.each do |m|
|
|
535
|
+
puts "- #{m['ID']}: #{m['NAME']}"
|
|
536
|
+
end
|
|
537
|
+
puts
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
# Iterate all the roles to ask for the marketplace
|
|
541
|
+
body['roles'].each do |role|
|
|
542
|
+
# Read role VM template information from OpenNebula
|
|
543
|
+
template = Template.new_with_id(role['vm_template'], @client)
|
|
544
|
+
rc = template.info
|
|
545
|
+
|
|
546
|
+
return rc if OpenNebula.is_error?(rc)
|
|
547
|
+
|
|
548
|
+
next if markets.include?(template['ID'])
|
|
549
|
+
|
|
550
|
+
if market
|
|
551
|
+
m = market
|
|
552
|
+
else
|
|
553
|
+
# Keep asking while user selects an incorrect marketplace
|
|
554
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, m)
|
|
555
|
+
print 'Where do you want to import' \
|
|
556
|
+
"`#{template['NAME']}`? (default=#{default_mp})"
|
|
557
|
+
m = STDIN.readline.chop
|
|
558
|
+
|
|
559
|
+
if m.empty?
|
|
560
|
+
puts default_mp
|
|
561
|
+
m = default_mp
|
|
562
|
+
else
|
|
563
|
+
m = m.to_i
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# Update current template information
|
|
569
|
+
markets[template['ID']] = {}
|
|
570
|
+
markets[template['ID']][:market] = m
|
|
571
|
+
markets[template['ID']][:template] = template
|
|
572
|
+
end
|
|
573
|
+
else
|
|
574
|
+
# Do not ask for marketplaces, just fill templates information
|
|
575
|
+
body['roles'].each do |role|
|
|
576
|
+
# Read role VM template information from OpenNebula
|
|
577
|
+
template = Template.new_with_id(role['vm_template'], @client)
|
|
578
|
+
rc = template.info
|
|
579
|
+
|
|
580
|
+
return rc if OpenNebula.is_error?(rc)
|
|
581
|
+
|
|
582
|
+
next if markets.include?(template['ID'])
|
|
583
|
+
|
|
584
|
+
# update current template information
|
|
585
|
+
markets[template['id']] = {}
|
|
586
|
+
markets[template['id']][:template] = template
|
|
587
|
+
end
|
|
215
588
|
end
|
|
216
589
|
|
|
217
|
-
|
|
590
|
+
markets
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
# Create applications in Marketplace
|
|
594
|
+
#
|
|
595
|
+
# @param markets [Hash] Marketplaces and templates information
|
|
596
|
+
# @param import_all [String] yes to import images too, no otherwise
|
|
597
|
+
# @param template_name [String] Virtual Machine Template app name
|
|
598
|
+
#
|
|
599
|
+
# @return [String] Error message in case of any
|
|
600
|
+
def create_apps(markets, import_all, template_name = nil)
|
|
601
|
+
ids = nil
|
|
602
|
+
|
|
603
|
+
markets.each do |_, market|
|
|
604
|
+
template = market[:template]
|
|
605
|
+
|
|
606
|
+
template.extend(OpenNebula::TemplateExt)
|
|
607
|
+
|
|
608
|
+
rc, ids = template.mp_import(market[:market].to_i,
|
|
609
|
+
import_all,
|
|
610
|
+
template_name)
|
|
218
611
|
|
|
219
|
-
|
|
220
|
-
template << "TYPE=image\n"
|
|
612
|
+
return [rc.message, ids] if OpenNebula.is_error?(rc)
|
|
221
613
|
|
|
222
|
-
|
|
614
|
+
# Store name to use it after
|
|
615
|
+
market[:name] = nil
|
|
616
|
+
market[:name] = rc
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
['', ids]
|
|
223
620
|
end
|
|
621
|
+
|
|
224
622
|
end
|