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.
Files changed (102) hide show
  1. checksums.yaml +5 -5
  2. data/bin/oneacct +5 -14
  3. data/bin/oneacl +4 -15
  4. data/bin/onecluster +6 -17
  5. data/bin/onedatastore +6 -17
  6. data/bin/oneflow +81 -23
  7. data/bin/oneflow-template +51 -27
  8. data/bin/onegroup +6 -17
  9. data/bin/onehook +6 -17
  10. data/bin/onehost +4 -15
  11. data/bin/oneimage +95 -18
  12. data/bin/onemarket +6 -17
  13. data/bin/onemarketapp +113 -20
  14. data/bin/onesecgroup +9 -17
  15. data/bin/oneshowback +14 -20
  16. data/bin/onetemplate +8 -18
  17. data/bin/oneuser +26 -17
  18. data/bin/onevcenter +6 -28
  19. data/bin/onevdc +6 -17
  20. data/bin/onevm +142 -21
  21. data/bin/onevmgroup +9 -17
  22. data/bin/onevnet +4 -15
  23. data/bin/onevntemplate +7 -17
  24. data/bin/onevrouter +6 -17
  25. data/bin/onezone +6 -17
  26. data/lib/cli_helper.rb +7 -10
  27. data/lib/command_parser.rb +1 -1
  28. data/lib/one_helper/oneacct_helper.rb +9 -22
  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 +9 -9
  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 +92 -30
  102. data/lib/one_helper/oneprovision_helper.rb +0 -362
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2023, 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