opennebula-cli 5.12.10 → 5.13.80.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/bin/oneacct +9 -4
  3. data/bin/oneacl +8 -5
  4. data/bin/onecluster +10 -7
  5. data/bin/onedatastore +10 -7
  6. data/bin/oneflow +85 -13
  7. data/bin/oneflow-template +45 -8
  8. data/bin/onegroup +10 -7
  9. data/bin/onehook +10 -7
  10. data/bin/onehost +8 -5
  11. data/bin/oneimage +99 -8
  12. data/bin/onemarket +10 -7
  13. data/bin/onemarketapp +117 -10
  14. data/bin/onesecgroup +13 -7
  15. data/bin/oneshowback +18 -10
  16. data/bin/onetemplate +12 -8
  17. data/bin/oneuser +30 -7
  18. data/bin/onevcenter +10 -18
  19. data/bin/onevdc +10 -7
  20. data/bin/onevm +146 -11
  21. data/bin/onevmgroup +13 -7
  22. data/bin/onevnet +8 -5
  23. data/bin/onevntemplate +11 -7
  24. data/bin/onevrouter +10 -7
  25. data/bin/onezone +10 -7
  26. data/lib/cli_helper.rb +4 -6
  27. data/lib/command_parser.rb +1 -1
  28. data/lib/one_helper/oneacct_helper.rb +8 -17
  29. data/lib/one_helper/oneacl_helper.rb +1 -1
  30. data/lib/one_helper/onecluster_helper.rb +1 -1
  31. data/lib/one_helper/onedatastore_helper.rb +11 -1
  32. data/lib/one_helper/oneflow_helper.rb +20 -5
  33. data/lib/one_helper/oneflowtemplate_helper.rb +28 -2
  34. data/lib/one_helper/onegroup_helper.rb +1 -1
  35. data/lib/one_helper/onehook_helper.rb +1 -1
  36. data/lib/one_helper/onehost_helper.rb +1 -5
  37. data/lib/one_helper/oneimage_helper.rb +7 -7
  38. data/lib/one_helper/onemarket_helper.rb +1 -1
  39. data/lib/one_helper/onemarketapp_helper.rb +494 -96
  40. data/lib/one_helper/onequota_helper.rb +1 -1
  41. data/lib/one_helper/onesecgroup_helper.rb +1 -1
  42. data/lib/one_helper/onetemplate_helper.rb +12 -1
  43. data/lib/one_helper/oneuser_helper.rb +11 -3
  44. data/lib/one_helper/onevcenter_helper.rb +176 -146
  45. data/lib/one_helper/onevdc_helper.rb +1 -1
  46. data/lib/one_helper/onevm_helper.rb +4 -3
  47. data/lib/one_helper/onevmgroup_helper.rb +1 -1
  48. data/lib/one_helper/onevnet_helper.rb +1 -1
  49. data/lib/one_helper/onevntemplate_helper.rb +1 -1
  50. data/lib/one_helper/onevrouter_helper.rb +1 -20
  51. data/lib/one_helper/onezone_helper.rb +12 -1
  52. data/lib/one_helper.rb +398 -37
  53. data/share/schemas/xsd/acct.xsd +179 -0
  54. data/share/schemas/xsd/acl_pool.xsd +22 -0
  55. data/share/schemas/xsd/api_info.xsd +43 -0
  56. data/share/schemas/xsd/cluster.xsd +34 -0
  57. data/share/schemas/xsd/cluster_pool.xsd +12 -0
  58. data/share/schemas/xsd/datastore.xsd +67 -0
  59. data/share/schemas/xsd/datastore_pool.xsd +12 -0
  60. data/share/schemas/xsd/document.xsd +42 -0
  61. data/share/schemas/xsd/document_pool.xsd +12 -0
  62. data/share/schemas/xsd/group.xsd +179 -0
  63. data/share/schemas/xsd/group_pool.xsd +194 -0
  64. data/share/schemas/xsd/hook.xsd +59 -0
  65. data/share/schemas/xsd/hook_message_api.xsd +14 -0
  66. data/share/schemas/xsd/hook_message_retry.xsd +12 -0
  67. data/share/schemas/xsd/hook_message_state.xsd +25 -0
  68. data/share/schemas/xsd/hook_pool.xsd +12 -0
  69. data/share/schemas/xsd/host.xsd +164 -0
  70. data/share/schemas/xsd/host_pool.xsd +12 -0
  71. data/share/schemas/xsd/image.xsd +123 -0
  72. data/share/schemas/xsd/image_pool.xsd +12 -0
  73. data/share/schemas/xsd/index.xsd +49 -0
  74. data/share/schemas/xsd/marketplace.xsd +44 -0
  75. data/share/schemas/xsd/marketplace_pool.xsd +12 -0
  76. data/share/schemas/xsd/marketplaceapp.xsd +56 -0
  77. data/share/schemas/xsd/marketplaceapp_pool.xsd +12 -0
  78. data/share/schemas/xsd/opennebula_configuration.xsd +412 -0
  79. data/share/schemas/xsd/raftstatus.xsd +18 -0
  80. data/share/schemas/xsd/security_group.xsd +74 -0
  81. data/share/schemas/xsd/security_group_pool.xsd +12 -0
  82. data/share/schemas/xsd/showback.xsd +29 -0
  83. data/share/schemas/xsd/user.xsd +186 -0
  84. data/share/schemas/xsd/user_pool.xsd +201 -0
  85. data/share/schemas/xsd/vdc.xsd +76 -0
  86. data/share/schemas/xsd/vdc_pool.xsd +12 -0
  87. data/share/schemas/xsd/vm.xsd +251 -0
  88. data/share/schemas/xsd/vm_group.xsd +59 -0
  89. data/share/schemas/xsd/vm_group_pool.xsd +12 -0
  90. data/share/schemas/xsd/vm_pool.xsd +114 -0
  91. data/share/schemas/xsd/vmtemplate.xsd +52 -0
  92. data/share/schemas/xsd/vmtemplate_pool.xsd +12 -0
  93. data/share/schemas/xsd/vnet.xsd +137 -0
  94. data/share/schemas/xsd/vnet_pool.xsd +85 -0
  95. data/share/schemas/xsd/vntemplate.xsd +50 -0
  96. data/share/schemas/xsd/vntemplate_pool.xsd +12 -0
  97. data/share/schemas/xsd/vrouter.xsd +49 -0
  98. data/share/schemas/xsd/vrouter_pool.xsd +12 -0
  99. data/share/schemas/xsd/zone.xsd +40 -0
  100. data/share/schemas/xsd/zone_pool.xsd +36 -0
  101. metadata +68 -7
  102. data/lib/one_helper/oneprovision_helper.rb +0 -362
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
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 => "name",
23
- :large => "--name name",
30
+ :name => 'name',
31
+ :large => '--name name',
24
32
  :format => String,
25
- :description => "Name of the new MarketPlaceApp"
33
+ :description => 'Name of the new MarketPlaceApp'
26
34
  },
27
35
  {
28
- :name => "description",
29
- :large => "--description description",
36
+ :name => 'description',
37
+ :large => '--description description',
30
38
  :format => String,
31
- :description => "Description for the new MarketPlaceApp"
39
+ :description => 'Description for the new MarketPlaceApp'
32
40
  },
33
41
  {
34
- :name => "image",
35
- :large => "--image id|name" ,
36
- :description => "Selects the image",
42
+ :name => 'image',
43
+ :large => '--image id|name',
44
+ :description => 'Selects the image',
37
45
  :format => String,
38
- :template_key => "origin_id",
39
- :proc => lambda { |o, options|
40
- OpenNebulaHelper.rname_to_id(o, "IMAGE")
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 => "vmname",
48
- :large => "--vmname name" ,
49
- :description => "Selects the name for the new VM Template, if the App contains one",
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
- "MARKETPLACEAPP"
66
+ 'MARKETPLACEAPP'
55
67
  end
56
68
 
57
69
  def self.conf_file
58
- "onemarketapp.yaml"
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
- return MarketPlaceApp::SHORT_MARKETPLACEAPP_STATES[state_str]
76
+ MarketPlaceApp::SHORT_MARKETPLACEAPP_STATES[state_str]
65
77
  end
66
78
 
67
- def format_pool(options)
68
- config_file = self.class.table_conf
69
-
70
- table = CLIHelper::ShowTable.new(config_file, self) do
71
- column :ID, "ONE identifier for the marketplace app", :size=>4 do |d|
72
- d["ID"]
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, "Name of the marketplace app", :left, :size=>25 do |d|
76
- d["NAME"]
87
+ column :NAME, 'Name of the marketplace app', :left, :size=>25 do |d|
88
+ d['NAME']
77
89
  end
78
90
 
79
- column :VERSION, "Version of the app", :size=>10 do |d|
80
- d["VERSION"]
91
+ column :VERSION, 'Version of the app', :size=>10 do |d|
92
+ d['VERSION']
81
93
  end
82
94
 
83
- column :SIZE, "App size", :size =>5 do |d|
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, "State of the app", :size=>4 do |d|
88
- OneMarketPlaceAppHelper.state_to_str(d["STATE"])
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, "Registration time of the app", :size=>8 do |d|
92
- Time.at(d['REGTIME'].to_i).strftime("%D")
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, "Marketplace app type", :size=>4 do |d|
96
- type = MarketPlaceApp::MARKETPLACEAPP_TYPES[d["TYPE"].to_i]
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, "Name of the MarketPlace", :left, :size=>20 do |d|
101
- d["MARKETPLACE"]
112
+ column :MARKET, 'Name of the MarketPlace', :left, :size=>20 do |d|
113
+ d['MARKETPLACE']
102
114
  end
103
115
 
104
- column :ZONE, "Zone ID", :size=>4 do |d|
105
- d["ZONE_ID"]
116
+ column :ZONE, 'Zone ID', :size=>4 do |d|
117
+ d['ZONE_ID']
106
118
  end
107
119
 
108
- default :ID,:NAME,:VERSION,:SIZE,:STAT,:TYPE,:REGTIME,:MARKET,:ZONE
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=-2)
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, options = {})
142
- str="%-15s: %-20s"
143
- str_h1="%-80s"
144
-
145
- CLIHelper.print_header(str_h1 % "MARKETPLACE APP #{app['ID']} INFORMATION")
146
- puts str % ["ID", app.id.to_s]
147
- puts str % ["NAME", app.name]
148
- puts str % ["TYPE", app.type_str]
149
- puts str % ["USER", app['UNAME']]
150
- puts str % ["GROUP", app['GNAME']]
151
- puts str % ["MARKETPLACE", app['MARKETPLACE']]
152
- puts str % ["STATE", OneMarketPlaceAppHelper.state_to_str(app["STATE"])]
153
- puts str % ["LOCK", OpenNebulaHelper.level_lock_to_str(app['LOCK/LOCKED'])]
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 % "PERMISSIONS",false)
408
+ CLIHelper.print_header(str_h1 % 'PERMISSIONS', false)
158
409
 
159
- ["OWNER", "GROUP", "OTHER"].each { |e|
160
- mask = "---"
161
- mask[0] = "u" if app["PERMISSIONS/#{e}_U"] == "1"
162
- mask[1] = "m" if app["PERMISSIONS/#{e}_M"] == "1"
163
- mask[2] = "a" if app["PERMISSIONS/#{e}_A"] == "1"
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 % [e, mask]
166
- }
416
+ puts format(str, e, mask)
417
+ end
167
418
  puts
168
419
 
169
- CLIHelper.print_header(str_h1 % "DETAILS", false)
170
-
171
- puts str % ["SOURCE", app['SOURCE']]
172
- puts str % ["MD5", app['MD5']]
173
- puts str % ["PUBLISHER", app['PUBLISHER']]
174
- puts str % ["REGISTER TIME", Time.at(app['REGTIME'].to_i).strftime("%c") ]
175
- puts str % ["VERSION", app['VERSION']]
176
- puts str % ["DESCRIPTION", app['DESCRIPTION']]
177
- puts str % ["SIZE", OpenNebulaHelper.unit_to_str(app['SIZE'].to_i,{},'M')]
178
- puts str % ["ORIGIN_ID", app['ORIGIN_ID']]
179
- puts str % ["FORMAT", app['FORMAT']]
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 % "IMPORT TEMPLATE", false)
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 % "MARKETPLACE APP TEMPLATE", false)
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
- def self.create_variables(options, name)
196
- if Array===name
197
- names=name
198
- else
199
- names=[name]
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
- t=''
203
- names.each do |n|
204
- if options[n]
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
- def self.create_datastore_template(options)
213
- template_options=TEMPLATE_OPTIONS.map do |o|
214
- o[:name].to_sym
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
- template=create_variables(options, template_options-[:dry,:image])
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
- template<<"ORIGIN_ID=#{options[:image]}\n" if options[:image]
220
- template << "TYPE=image\n"
612
+ return [rc.message, ids] if OpenNebula.is_error?(rc)
221
613
 
222
- [0, template]
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