opennebula-cli 5.12.8 → 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 +7 -4
  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.rb +398 -37
  29. data/lib/one_helper/oneacct_helper.rb +8 -17
  30. data/lib/one_helper/oneacl_helper.rb +1 -1
  31. data/lib/one_helper/onecluster_helper.rb +1 -1
  32. data/lib/one_helper/onedatastore_helper.rb +11 -1
  33. data/lib/one_helper/oneflow_helper.rb +20 -5
  34. data/lib/one_helper/oneflowtemplate_helper.rb +28 -2
  35. data/lib/one_helper/onegroup_helper.rb +1 -1
  36. data/lib/one_helper/onehook_helper.rb +1 -1
  37. data/lib/one_helper/onehost_helper.rb +1 -5
  38. data/lib/one_helper/oneimage_helper.rb +7 -7
  39. data/lib/one_helper/onemarket_helper.rb +1 -1
  40. data/lib/one_helper/onemarketapp_helper.rb +494 -96
  41. data/lib/one_helper/onequota_helper.rb +1 -1
  42. data/lib/one_helper/onesecgroup_helper.rb +1 -1
  43. data/lib/one_helper/onetemplate_helper.rb +12 -1
  44. data/lib/one_helper/oneuser_helper.rb +11 -3
  45. data/lib/one_helper/onevcenter_helper.rb +176 -146
  46. data/lib/one_helper/onevdc_helper.rb +1 -1
  47. data/lib/one_helper/onevm_helper.rb +4 -3
  48. data/lib/one_helper/onevmgroup_helper.rb +1 -1
  49. data/lib/one_helper/onevnet_helper.rb +1 -1
  50. data/lib/one_helper/onevntemplate_helper.rb +1 -1
  51. data/lib/one_helper/onevrouter_helper.rb +1 -20
  52. data/lib/one_helper/onezone_helper.rb +12 -1
  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 #
@@ -91,28 +91,19 @@ class AcctHelper < OpenNebulaHelper::OneHelper
91
91
  :format => String
92
92
  }
93
93
 
94
- XML = {
95
- :name => "xml",
96
- :short => "-x",
97
- :large => "--xml",
98
- :description => "Show the resource in xml format"
99
- }
100
-
101
- JSON = {
102
- :name => "json",
103
- :short => "-j",
104
- :large => "--json",
105
- :description => "Show the resource in json format"
106
- }
107
-
108
94
  SPLIT={
109
95
  :name => "split",
110
96
  :large => "--split",
111
97
  :description => "Split the output in a table for each VM"
112
98
  }
113
99
 
114
- ACCT_OPTIONS = [START_TIME_ACCT, END_TIME_ACCT, USERFILTER, GROUP, HOST, XPATH, XML, JSON, SPLIT]
115
- SHOWBACK_OPTIONS = [START_TIME_SHOWBACK, END_TIME_SHOWBACK, USERFILTER, GROUP, XML, JSON]
100
+ ACCT_OPTIONS = [START_TIME_ACCT, END_TIME_ACCT, USERFILTER, GROUP, HOST, XPATH, SPLIT]
101
+ SHOWBACK_OPTIONS = [START_TIME_SHOWBACK, END_TIME_SHOWBACK, USERFILTER, GROUP]
102
+
103
+ ACCT_OPTIONS << OpenNebulaHelper::XML
104
+ ACCT_OPTIONS << OpenNebulaHelper::JSON
105
+
106
+ SHOWBACK_OPTIONS += OpenNebulaHelper::FORMAT
116
107
 
117
108
  ACCT_TABLE = CLIHelper::ShowTable.new(self.table_conf("oneacct.yaml"), nil) do
118
109
  column :UID, "User ID", :size=>4 do |d|
@@ -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 #
@@ -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 #
@@ -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 #
@@ -28,6 +28,16 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
28
28
  }
29
29
  }
30
30
 
31
+ FILE_DATASTORE = {
32
+ :name => "file_datastore",
33
+ :large => "--file-datastore id|name" ,
34
+ :description => "Selects the file datastore",
35
+ :format => String,
36
+ :proc => lambda { |o, options|
37
+ OpenNebulaHelper.rname_to_id(o, "DATASTORE")
38
+ }
39
+ }
40
+
31
41
  def self.rname
32
42
  "DATASTORE"
33
43
  end
@@ -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 #
@@ -57,11 +57,18 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
57
57
  d['NAME']
58
58
  end
59
59
 
60
+ column :STARTTIME, 'Start time of the Service', :size => 15 do |d|
61
+ d.extend(CLIHelper::HashWithSearch)
62
+ d = d.dsearch('TEMPLATE/BODY')
63
+
64
+ OpenNebulaHelper.time_to_str(d['start_time'])
65
+ end
66
+
60
67
  column :STAT, 'State', :size => 11, :left => true do |d|
61
68
  Service.state_str(d['TEMPLATE']['BODY']['state'])
62
69
  end
63
70
 
64
- default :ID, :USER, :GROUP, :NAME, :STAT
71
+ default :ID, :USER, :GROUP, :NAME, :STARTTIME, :STAT
65
72
  end
66
73
  end
67
74
 
@@ -74,6 +81,8 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
74
81
 
75
82
  if CloudClient.is_error?(response)
76
83
  [response.code.to_i, response.to_s]
84
+ elsif options[:yaml]
85
+ [0, JSON.parse(response.body).to_yaml(:indent => 4)]
77
86
  else
78
87
  array_list = JSON.parse(response.body)
79
88
  array_list = array_list['DOCUMENT_POOL']['DOCUMENT']
@@ -93,6 +102,8 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
93
102
  else
94
103
  [0, JSON.pretty_generate(array_list)]
95
104
  end
105
+ elsif options[:yaml]
106
+ [0, array_list.to_yaml(:indent => 4)]
96
107
  else
97
108
  format_service_pool.show(array_list)
98
109
 
@@ -139,6 +150,8 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
139
150
  else
140
151
  if options[:json]
141
152
  [0, response.body]
153
+ elsif options[:yaml]
154
+ [0, JSON.parse(response.body).to_yaml(:indent => 4)]
142
155
  else
143
156
  str_h1 = '%-80s'
144
157
  document = JSON.parse(response.body)['DOCUMENT']
@@ -260,9 +273,10 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
260
273
  #
261
274
  # @param document [Hash] Service document information
262
275
  def print_service_info(document)
263
- str = '%-20s: %-20s'
264
- str_h1 = '%-80s'
265
- template = document['TEMPLATE']['BODY']
276
+ str = '%-20s: %-20s'
277
+ str_h1 = '%-80s'
278
+ template = document['TEMPLATE']['BODY']
279
+ start_time = OpenNebulaHelper.time_to_str(template['start_time'])
266
280
 
267
281
  puts Kernel.format(str, 'ID', document['ID'])
268
282
  puts Kernel.format(str, 'NAME', document['NAME'])
@@ -273,6 +287,7 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
273
287
  puts Kernel.format(str,
274
288
  'SERVICE STATE',
275
289
  Service.state_str(template['state']))
290
+ puts Kernel.format(str, 'START TIME', start_time)
276
291
 
277
292
  if template['shutdown_action']
278
293
  puts Kernel.format(str, 'SHUTDOWN', template['shutdown_action'])
@@ -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 #
@@ -57,7 +57,16 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
57
57
  d['NAME']
58
58
  end
59
59
 
60
- default :ID, :USER, :GROUP, :NAME
60
+ column :REGTIME,
61
+ 'Registration time of the Service Template',
62
+ :size => 15 do |d|
63
+ d.extend(CLIHelper::HashWithSearch)
64
+ d = d.dsearch('TEMPLATE/BODY')
65
+
66
+ OpenNebulaHelper.time_to_str(d['registration_time'])
67
+ end
68
+
69
+ default :ID, :USER, :GROUP, :NAME, :REGTIME
61
70
  end
62
71
  end
63
72
 
@@ -73,6 +82,8 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
73
82
  else
74
83
  if options[:json]
75
84
  [0, response.body]
85
+ elsif options[:yaml]
86
+ [0, JSON.parse(response.body).to_yaml(:indent => 4)]
76
87
  else
77
88
  documents = JSON.parse(response.body)['DOCUMENT_POOL']
78
89
  format_service_template_pool.show(documents['DOCUMENT'])
@@ -120,12 +131,17 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
120
131
  else
121
132
  if options[:json]
122
133
  [0, response.body]
134
+ elsif options[:yaml]
135
+ [0, JSON.parse(response.body).to_yaml(:indent => 4)]
123
136
  else
124
137
  str = '%-20s: %-20s'
125
138
  str_h1 = '%-80s'
126
139
 
127
140
  document = JSON.parse(response.body)['DOCUMENT']
128
141
  template = document['TEMPLATE']['BODY']
142
+ reg_time = OpenNebulaHelper.time_to_str(
143
+ template['registration_time']
144
+ )
129
145
 
130
146
  CLIHelper.print_header(
131
147
  str_h1 % "SERVICE TEMPLATE #{document['ID']} INFORMATION"
@@ -135,6 +151,7 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
135
151
  puts Kernel.format str, 'NAME', document['NAME']
136
152
  puts Kernel.format str, 'USER', document['UNAME']
137
153
  puts Kernel.format str, 'GROUP', document['GNAME']
154
+ puts Kernel.format str, 'REGISTRATION TIME', reg_time
138
155
 
139
156
  puts
140
157
 
@@ -309,4 +326,13 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
309
326
  answers
310
327
  end
311
328
 
329
+ def factory(id = nil)
330
+ if id
331
+ OpenNebula::ServiceTemplate.new_with_id(id, @client)
332
+ else
333
+ xml = OpenNebula::ServiceTemplate.build_xml
334
+ OpenNebula::ServiceTemplate.new(xml, @client)
335
+ end
336
+ end
337
+
312
338
  end
@@ -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 #
@@ -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 #
@@ -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 #
@@ -222,10 +222,6 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
222
222
  end
223
223
  end
224
224
 
225
- column :PROVIDER, 'Host provider', :left, :size => 6 do |d|
226
- d['TEMPLATE']['PM_MAD'].nil? ? '-' : d['TEMPLATE']['PM_MAD']
227
- end
228
-
229
225
  column :STAT, 'Host status', :left, :size => 6 do |d|
230
226
  OneHostHelper.state_to_str(d['STATE'])
231
227
  end
@@ -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 #
@@ -22,7 +22,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
22
22
 
23
23
  # This list contains prefixes that should skip adding user home to the path
24
24
  # This must have the same content as the case $FROM in downloader.sh
25
- PREFIXES = %w[http https ssh s3 rbd vcenter lxd docker]
25
+ PREFIXES = %w[http https ssh s3 rbd vcenter lxd docker dockerfile]
26
26
 
27
27
  TEMPLATE_OPTIONS=[
28
28
  {
@@ -98,9 +98,9 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
98
98
  end
99
99
  },
100
100
  {
101
- :name => 'driver',
102
- :large => '--driver driver',
103
- :description => 'Driver to use image (raw, qcow2, tap:aio:...)',
101
+ :name => 'format',
102
+ :large => '--format format',
103
+ :description => 'Format of the image (raw, qcow2, ...)',
104
104
  :format => String
105
105
  },
106
106
  {
@@ -295,7 +295,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
295
295
  str_h1='%-80s'
296
296
 
297
297
  path = image['PATH']
298
- fstype = image['FSTYPE']
298
+ iformat = image['FORMAT']
299
299
 
300
300
  size = OpenNebulaHelper.unit_to_str(image['SIZE'].to_i, {}, 'M')
301
301
  lock = OpenNebulaHelper.level_lock_to_str(image['LOCK/LOCKED'])
@@ -314,7 +314,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
314
314
  puts format(str, 'PERSISTENT', pers)
315
315
  puts format(str, 'SOURCE', image['SOURCE'])
316
316
  puts format(str, 'PATH', path) if path && !path.empty?
317
- puts format(str, 'FSTYPE', fstype) if fstype && !fstype.empty?
317
+ puts format(str, 'FORMAT', iformat) if iformat && !iformat.empty?
318
318
  puts format(str, 'SIZE', size)
319
319
  puts format(str, 'STATE', image.short_state_str)
320
320
  puts format(str, 'RUNNING_VMS', image['RUNNING_VMS'])
@@ -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 #
@@ -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