opennebula-cli 5.12.5 → 5.13.85.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 +10 -7
  11. data/bin/oneimage +100 -9
  12. data/bin/onemarket +10 -7
  13. data/bin/onemarketapp +118 -11
  14. data/bin/onesecgroup +13 -7
  15. data/bin/oneshowback +23 -10
  16. data/bin/onetemplate +16 -9
  17. data/bin/oneuser +30 -7
  18. data/bin/onevcenter +7 -4
  19. data/bin/onevdc +10 -7
  20. data/bin/onevm +147 -12
  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 +6 -8
  27. data/lib/command_parser.rb +1 -1
  28. data/lib/one_helper.rb +414 -46
  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 +500 -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 +16 -4
  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 +13 -6
  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 +79 -18
  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,242 @@ 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
+ # Turn import all into a boolean
202
+ import_all == 'yes' ? import_all = true : import_all = false
203
+
204
+ main_market = options[:market]
205
+
206
+ # Read marketplace where import the service template
207
+ # It can only be a private marketplace
208
+ unless main_market
209
+ puts
210
+ puts 'Available Marketplaces (please enter ID)'
211
+ pool.each {|market| puts "- #{market['ID']}: #{market['NAME']}" }
212
+ puts
213
+ end
214
+
215
+ default_mp = pool.first['ID'].to_i
216
+
217
+ # Keep asking while user selects an incorrect marketplace
218
+ until OneMarketPlaceAppHelper.market_exist?(pool, main_market)
219
+ print 'Where do you want to import the Service template? ' \
220
+ "(default=#{default_mp})"
221
+ main_market = STDIN.readline.chop
222
+
223
+ if main_market.empty?
224
+ puts default_mp
225
+ main_market = default_mp
226
+ else
227
+ main_market = main_market.to_i
228
+ end
229
+ end
230
+
231
+ markets = import_service_template_roles(import_all,
232
+ body,
233
+ pool,
234
+ options[:market])
235
+ ids = []
236
+
237
+ # Create roles apps
238
+ if import_all
239
+ rc = create_apps(markets, import_all)
240
+ ids = rc[1]
241
+
242
+ return [-1, rc[0]] unless rc[0].empty?
243
+ end
244
+
245
+ # Create service template app
246
+ s_template.extend(ServiceTemplateExt)
247
+
248
+ rc = s_template.mp_import(markets, main_market, options[:vmname])
249
+
250
+ if rc[0] == -1
251
+ rc
252
+ else
253
+ ids.each {|i| puts "ID: #{i}" }
254
+ puts "ID: #{rc[1]}"
255
+ [0, nil]
256
+ end
257
+ end
258
+
259
+ # Import VM Template into marketplace
260
+ #
261
+ # @param id [Integer] VM Template ID
262
+ # @param options [Hash] User CLI options
263
+ #
264
+ # @return [Error code, error message] 0 if everything was correct
265
+ # 1 otherwhise
266
+ def import_vm_template(id, options)
267
+ pool = private_markets
268
+
269
+ return pool if OpenNebula.is_error?(pool)
270
+
271
+ template = Template.new_with_id(id, @client)
272
+ rc = template.info
273
+
274
+ return rc if OpenNebula.is_error?(rc)
275
+
276
+ import_all = options[:yes] || options[:no]
277
+
278
+ while import_all != 'no' && import_all != 'yes'
279
+ print 'Do you want to import images too? (yes/no, default=yes): '
280
+ import_all = STDIN.readline.chop.downcase
281
+
282
+ if import_all.empty?
283
+ puts 'yes'
284
+ import_all = 'yes'
285
+ end
286
+ end
287
+
288
+ # Turn import all into a boolean
289
+ import_all == 'yes' ? import_all = true : import_all = false
290
+
291
+ main_market = options[:market]
292
+
293
+ # Read marketplace where import the VM template
294
+ # It can only be a private marketplace
295
+ unless main_market
296
+ puts
297
+ puts 'Available Marketplaces (please enter ID)'
298
+ pool.each {|market| puts "- #{market['ID']}: #{market['NAME']}" }
299
+ puts
300
+ end
301
+
302
+ default_mp = pool.first['ID'].to_i
303
+
304
+ # Keep asking while user selects an incorrect marketplace
305
+ until OneMarketPlaceAppHelper.market_exist?(pool, main_market)
306
+ print 'Where do you want to import the VM template? ' \
307
+ "(default=#{default_mp})"
308
+ main_market = STDIN.readline.chop
309
+
310
+ if main_market.empty?
311
+ puts default_mp
312
+ main_market = default_mp
313
+ else
314
+ main_market = main_market.to_i
315
+ end
316
+ end
317
+
318
+ # Templates import information
319
+ #
320
+ # template_id => :market => marketplace ID to import it
321
+ # :template => ONE Template information
322
+ # :name => generated name for the template
323
+ markets = {}
324
+ markets[template['ID']] = {}
325
+ markets[template['ID']][:market] = main_market
326
+ markets[template['ID']][:template] = template
327
+
328
+ rc = create_apps(markets, import_all, options[:vmname])
329
+
330
+ if rc[0] == -1
331
+ rc
332
+ else
333
+ rc[1].each {|i| puts "ID: #{i}" }
334
+ [0, nil]
335
+ end
336
+ end
337
+
338
+ # Save VM as template to be able to import it
339
+ #
340
+ # @param id [Integer] VM ID
341
+ #
342
+ # @return [Integer] New template ID
343
+ def save_as_template(id)
344
+ vm = VirtualMachine.new_with_id(id, @client)
345
+ rc = vm.info
346
+
347
+ return rc if OpenNebula.is_error?(rc)
348
+
349
+ vm.extend(VirtualMachineExt)
350
+
351
+ vm.save_as_template("#{vm['NAME']}-saved", 'App to import')
352
+ end
353
+
354
+ # Get object ID from name
355
+ #
356
+ # @param id [String] ID or NAME
357
+ # @param obj [OpenNebula::Class] OpenNebula pool class
358
+ #
359
+ # @return [Integer] Object ID
360
+ def get_obj_id(id, obj)
361
+ if (id.is_a? Integer) || id.match(/^\d+$/)
362
+ id.to_i
363
+ else
364
+ pool = obj.new(@client)
365
+ rc = pool.info_all
366
+
367
+ return rc if OpenNebula.is_error?(rc)
368
+
369
+ rc = pool.find {|v| v['NAME'] == id }
370
+
371
+ return Error.new("Object `#{id}` not found") unless rc
372
+
373
+ rc['ID'].to_i
374
+ end
375
+ end
376
+
126
377
  private
127
378
 
128
- def factory(id=nil)
379
+ def factory(id = nil)
129
380
  if id
130
381
  OpenNebula::MarketPlaceApp.new_with_id(id, @client)
131
382
  else
@@ -134,91 +385,244 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
134
385
  end
135
386
  end
136
387
 
137
- def factory_pool(user_flag=-2)
388
+ def factory_pool(user_flag = -2)
138
389
  OpenNebula::MarketPlaceAppPool.new(@client, user_flag)
139
390
  end
140
391
 
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'])]
392
+ def format_resource(app, _options = {})
393
+ str='%-15s: %-20s'
394
+ str_h1='%-80s'
395
+
396
+ CLIHelper.print_header(
397
+ str_h1 % "MARKETPLACE APP #{app['ID']} INFORMATION"
398
+ )
399
+ puts format(str, 'ID', app.id.to_s)
400
+ puts format(str, 'NAME', app.name)
401
+ puts format(str, 'TYPE', app.type_str)
402
+ puts format(str, 'USER', app['UNAME'])
403
+ puts format(str, 'GROUP', app['GNAME'])
404
+ puts format(str, 'MARKETPLACE', app['MARKETPLACE'])
405
+ puts format(str,
406
+ 'STATE',
407
+ OneMarketPlaceAppHelper.state_to_str(app['STATE']))
408
+ puts format(str,
409
+ 'LOCK',
410
+ OpenNebulaHelper.level_lock_to_str(app['LOCK/LOCKED']))
154
411
 
155
412
  puts
156
413
 
157
- CLIHelper.print_header(str_h1 % "PERMISSIONS",false)
414
+ CLIHelper.print_header(str_h1 % 'PERMISSIONS', false)
158
415
 
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"
416
+ %w[OWNER GROUP OTHER].each do |e|
417
+ mask = '---'
418
+ mask[0] = 'u' if app["PERMISSIONS/#{e}_U"] == '1'
419
+ mask[1] = 'm' if app["PERMISSIONS/#{e}_M"] == '1'
420
+ mask[2] = 'a' if app["PERMISSIONS/#{e}_A"] == '1'
164
421
 
165
- puts str % [e, mask]
166
- }
422
+ puts format(str, e, mask)
423
+ end
167
424
  puts
168
425
 
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']]
426
+ CLIHelper.print_header(str_h1 % 'DETAILS', false)
427
+
428
+ puts format(str, 'SOURCE', app['SOURCE'])
429
+ puts format(str, 'MD5', app['MD5'])
430
+ puts format(str, 'PUBLISHER', app['PUBLISHER'])
431
+ puts format(str,
432
+ 'REGISTER TIME',
433
+ Time.at(app['REGTIME'].to_i).strftime('%c'))
434
+ puts format(str, 'VERSION', app['VERSION'])
435
+ puts format(str, 'DESCRIPTION', app['DESCRIPTION'])
436
+ puts format(str,
437
+ 'SIZE',
438
+ OpenNebulaHelper.unit_to_str(app['SIZE'].to_i, {}, 'M'))
439
+ puts format(str, 'ORIGIN_ID', app['ORIGIN_ID'])
440
+ puts format(str, 'FORMAT', app['FORMAT'])
180
441
 
181
442
  puts
182
443
 
183
- CLIHelper.print_header(str_h1 % "IMPORT TEMPLATE", false)
444
+ CLIHelper.print_header(str_h1 % 'IMPORT TEMPLATE', false)
184
445
 
185
446
  puts Base64.decode64(app['APPTEMPLATE64'])
186
447
 
187
448
  puts
188
449
 
189
- CLIHelper.print_header(str_h1 % "MARKETPLACE APP TEMPLATE", false)
450
+ CLIHelper.print_header(str_h1 % 'MARKETPLACE APP TEMPLATE', false)
190
451
  puts app.template_str
191
452
 
192
453
  puts
193
454
  end
194
455
 
195
- def self.create_variables(options, name)
196
- if Array===name
197
- names=name
198
- else
199
- names=[name]
456
+ class << self
457
+
458
+ def create_variables(options, name)
459
+ names = [name].flatten
460
+ t = ''
461
+
462
+ names.each do |n|
463
+ next unless options[n]
464
+
465
+ t << "#{n.to_s.upcase}=\"#{options[n]}\"\n"
466
+ end
467
+
468
+ t
200
469
  end
201
470
 
202
- t=''
203
- names.each do |n|
204
- if options[n]
205
- t<<"#{n.to_s.upcase}=\"#{options[n]}\"\n"
471
+ def create_datastore_template(options)
472
+ template_options = TEMPLATE_OPTIONS.map do |o|
473
+ o[:name].to_sym
206
474
  end
475
+
476
+ template = create_variables(options,
477
+ template_options-[:dry, :image])
478
+
479
+ template << "ORIGIN_ID=#{options[:image]}\n" if options[:image]
480
+ template << "TYPE=image\n"
481
+
482
+ [0, template]
483
+ end
484
+
485
+ # Check if marketplace exists
486
+ #
487
+ # @param pool [MarketPlacePool] Marketplaces pool
488
+ # @param market [String] ID to check
489
+ #
490
+ # @return [Boolean] True if exists, false otherwise
491
+ def market_exist?(pool, market)
492
+ !pool.select {|v| v['ID'].to_i == market }.empty?
207
493
  end
208
494
 
209
- t
210
495
  end
211
496
 
212
- def self.create_datastore_template(options)
213
- template_options=TEMPLATE_OPTIONS.map do |o|
214
- o[:name].to_sym
497
+ # Get private marketplace to import templates
498
+ #
499
+ # @return [OpenNebula::Pool] Marketplace pool or error if any
500
+ def private_markets
501
+ pool = MarketPlacePool.new(@client)
502
+ rc = pool.info
503
+
504
+ return rc if OpenNebula.is_error?(rc)
505
+
506
+ # Get private marketplaces
507
+ pool = pool.select {|market| MARKETS.include?(market['MARKET_MAD']) }
508
+ pool = pool.sort_by {|market| market['ID'].to_i }
509
+
510
+ if pool.empty?
511
+ return Error.new("There are no #{MARKETS.join('/')} marketplaces")
215
512
  end
216
513
 
217
- template=create_variables(options, template_options-[:dry,:image])
514
+ pool
515
+ end
516
+
517
+ # Get roles information when importing a service template into marketplace
518
+ #
519
+ # @param import_all [Boolean] true to import VM templates too
520
+ # @param body [Hash] Sevice Template information
521
+ # @param pool [Array] Marketplace pool
522
+ # @param market [Integer] Marketplace to import
523
+ #
524
+ # @return [Hash] Roles templates and marketplaces to import them
525
+ def import_service_template_roles(import_all, body, pool, market)
526
+ # Templates import information
527
+ #
528
+ # template_id => :market => marketplace ID to import it
529
+ # :template => ONE Template information
530
+ # :name => generated name for the template
531
+ markets = {}
532
+ default_mp = pool.first['ID'].to_i
533
+
534
+ if import_all
535
+ # Read marketplace where import each different VM template
536
+ # It can only be a private marketplace
537
+ unless market
538
+ puts
539
+ puts 'Available Marketplaces for roles (please enter ID)'
540
+ pool.each do |m|
541
+ puts "- #{m['ID']}: #{m['NAME']}"
542
+ end
543
+ puts
544
+ end
545
+
546
+ # Iterate all the roles to ask for the marketplace
547
+ body['roles'].each do |role|
548
+ # Read role VM template information from OpenNebula
549
+ template = Template.new_with_id(role['vm_template'], @client)
550
+ rc = template.info
551
+
552
+ return rc if OpenNebula.is_error?(rc)
553
+
554
+ next if markets.include?(template['ID'])
555
+
556
+ if market
557
+ m = market
558
+ else
559
+ # Keep asking while user selects an incorrect marketplace
560
+ until OneMarketPlaceAppHelper.market_exist?(pool, m)
561
+ print 'Where do you want to import' \
562
+ "`#{template['NAME']}`? (default=#{default_mp})"
563
+ m = STDIN.readline.chop
564
+
565
+ if m.empty?
566
+ puts default_mp
567
+ m = default_mp
568
+ else
569
+ m = m.to_i
570
+ end
571
+ end
572
+ end
573
+
574
+ # Update current template information
575
+ markets[template['ID']] = {}
576
+ markets[template['ID']][:market] = m
577
+ markets[template['ID']][:template] = template
578
+ end
579
+ else
580
+ # Do not ask for marketplaces, just fill templates information
581
+ body['roles'].each do |role|
582
+ # Read role VM template information from OpenNebula
583
+ template = Template.new_with_id(role['vm_template'], @client)
584
+ rc = template.info
218
585
 
219
- template<<"ORIGIN_ID=#{options[:image]}\n" if options[:image]
220
- template << "TYPE=image\n"
586
+ return rc if OpenNebula.is_error?(rc)
221
587
 
222
- [0, template]
588
+ next if markets.include?(template['ID'])
589
+
590
+ # update current template information
591
+ markets[template['id']] = {}
592
+ markets[template['id']][:template] = template
593
+ end
594
+ end
595
+
596
+ markets
597
+ end
598
+
599
+ # Create applications in Marketplace
600
+ #
601
+ # @param markets [Hash] Marketplaces and templates information
602
+ # @param import_all [Boolean] true to import images too
603
+ # @param template_name [String] Virtual Machine Template app name
604
+ #
605
+ # @return [String] Error message in case of any
606
+ def create_apps(markets, import_all, template_name = nil)
607
+ ids = nil
608
+
609
+ markets.each do |_, market|
610
+ template = market[:template]
611
+
612
+ template.extend(OpenNebula::TemplateExt)
613
+
614
+ rc, ids = template.mp_import(market[:market].to_i,
615
+ import_all,
616
+ template_name)
617
+
618
+ return [rc.message, ids] if OpenNebula.is_error?(rc)
619
+
620
+ # Store name to use it after
621
+ market[:name] = nil
622
+ market[:name] = rc
623
+ end
624
+
625
+ ['', ids]
223
626
  end
627
+
224
628
  end