opennebula-cli 5.12.9 → 6.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) 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 +114 -11
  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 +8 -11
  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 +11 -8
  26. data/lib/cli_helper.rb +17 -8
  27. data/lib/command_parser.rb +17 -14
  28. data/lib/one_helper.rb +401 -39
  29. data/lib/one_helper/oneacct_helper.rb +6 -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 +13 -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 +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 +24 -17
  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 +50 -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/monitoring_data.xsd +41 -0
  79. data/share/schemas/xsd/opennebula_configuration.xsd +412 -0
  80. data/share/schemas/xsd/raftstatus.xsd +18 -0
  81. data/share/schemas/xsd/security_group.xsd +74 -0
  82. data/share/schemas/xsd/security_group_pool.xsd +12 -0
  83. data/share/schemas/xsd/showback.xsd +29 -0
  84. data/share/schemas/xsd/user.xsd +186 -0
  85. data/share/schemas/xsd/user_pool.xsd +201 -0
  86. data/share/schemas/xsd/vdc.xsd +76 -0
  87. data/share/schemas/xsd/vdc_pool.xsd +12 -0
  88. data/share/schemas/xsd/vm.xsd +251 -0
  89. data/share/schemas/xsd/vm_group.xsd +59 -0
  90. data/share/schemas/xsd/vm_group_pool.xsd +12 -0
  91. data/share/schemas/xsd/vm_pool.xsd +114 -0
  92. data/share/schemas/xsd/vmtemplate.xsd +52 -0
  93. data/share/schemas/xsd/vmtemplate_pool.xsd +12 -0
  94. data/share/schemas/xsd/vnet.xsd +137 -0
  95. data/share/schemas/xsd/vnet_pool.xsd +85 -0
  96. data/share/schemas/xsd/vntemplate.xsd +50 -0
  97. data/share/schemas/xsd/vntemplate_pool.xsd +12 -0
  98. data/share/schemas/xsd/vrouter.xsd +49 -0
  99. data/share/schemas/xsd/vrouter_pool.xsd +12 -0
  100. data/share/schemas/xsd/zone.xsd +40 -0
  101. data/share/schemas/xsd/zone_pool.xsd +36 -0
  102. metadata +67 -5
  103. data/lib/one_helper/oneprovision_helper.rb +0 -362
data/bin/onevmgroup CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # -------------------------------------------------------------------------- #
4
- # Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
4
+ # Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
5
5
  # #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
7
7
  # not use this file except in compliance with the License. You may obtain #
@@ -27,9 +27,12 @@ else
27
27
  end
28
28
 
29
29
  if File.directory?(GEMS_LOCATION)
30
- $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
31
- require 'rubygems'
32
- Gem.use_paths(File.realpath(GEMS_LOCATION))
30
+ real_gems_path = File.realpath(GEMS_LOCATION)
31
+ if !defined?(Gem) || Gem.path != [real_gems_path]
32
+ $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
33
+ require 'rubygems'
34
+ Gem.use_paths(real_gems_path)
35
+ end
33
36
  end
34
37
 
35
38
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -77,8 +80,8 @@ CommandParser::CmdParser.new(ARGV) do
77
80
  ########################################################################
78
81
  set :option, CommandParser::OPTIONS + OpenNebulaHelper::CLIENT_OPTIONS
79
82
 
80
- list_options = CLIHelper::OPTIONS
81
- list_options << OpenNebulaHelper::XML
83
+ list_options = CLIHelper::OPTIONS
84
+ list_options += OpenNebulaHelper::FORMAT
82
85
  list_options << OpenNebulaHelper::NUMERIC
83
86
  list_options << OpenNebulaHelper::DESCRIBE
84
87
 
@@ -148,7 +151,10 @@ CommandParser::CmdParser.new(ARGV) do
148
151
  Shows information for the given VM Group
149
152
  EOT
150
153
 
151
- command :show, show_desc, :vmgroupid, :options => OpenNebulaHelper::XML do
154
+ command :show,
155
+ show_desc,
156
+ :vmgroupid,
157
+ :options => OpenNebulaHelper::FORMAT do
152
158
  helper.show_resource(args[0], options)
153
159
  end
154
160
 
data/bin/onevnet CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # -------------------------------------------------------------------------- #
4
- # Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
4
+ # Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
5
5
  # #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
7
7
  # not use this file except in compliance with the License. You may obtain #
@@ -27,9 +27,12 @@ else
27
27
  end
28
28
 
29
29
  if File.directory?(GEMS_LOCATION)
30
- $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
31
- require 'rubygems'
32
- Gem.use_paths(File.realpath(GEMS_LOCATION))
30
+ real_gems_path = File.realpath(GEMS_LOCATION)
31
+ if !defined?(Gem) || Gem.path != [real_gems_path]
32
+ $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
33
+ require 'rubygems'
34
+ Gem.use_paths(real_gems_path)
35
+ end
33
36
  end
34
37
 
35
38
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -320,7 +323,7 @@ CommandParser::CmdParser.new(ARGV) do
320
323
  EOT
321
324
 
322
325
  command :show, show_desc, :vnetid,
323
- :options => [OpenNebulaHelper::XML,
326
+ :options => [OpenNebulaHelper::FORMAT,
324
327
  OpenNebulaHelper::DECRYPT,
325
328
  OneVNetHelper::SHOW_AR] do
326
329
  helper.show_resource(args[0], options)
data/bin/onevntemplate CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # -------------------------------------------------------------------------- #
4
- # Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
4
+ # Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
5
5
  # #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
7
7
  # not use this file except in compliance with the License. You may obtain #
@@ -27,9 +27,12 @@ else
27
27
  end
28
28
 
29
29
  if File.directory?(GEMS_LOCATION)
30
- $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
31
- require 'rubygems'
32
- Gem.use_paths(File.realpath(GEMS_LOCATION))
30
+ real_gems_path = File.realpath(GEMS_LOCATION)
31
+ if !defined?(Gem) || Gem.path != [real_gems_path]
32
+ $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
33
+ require 'rubygems'
34
+ Gem.use_paths(real_gems_path)
35
+ end
33
36
  end
34
37
 
35
38
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -78,8 +81,8 @@ CommandParser::CmdParser.new(ARGV) do
78
81
  ########################################################################
79
82
  set :option, CommandParser::OPTIONS + OpenNebulaHelper::CLIENT_OPTIONS
80
83
 
81
- list_options = CLIHelper::OPTIONS
82
- list_options << OpenNebulaHelper::XML
84
+ list_options = CLIHelper::OPTIONS
85
+ list_options += OpenNebulaHelper::FORMAT
83
86
  list_options << OpenNebulaHelper::NUMERIC
84
87
  list_options << OpenNebulaHelper::DESCRIBE
85
88
 
@@ -313,7 +316,8 @@ CommandParser::CmdParser.new(ARGV) do
313
316
  EOT
314
317
 
315
318
  command :show, show_desc, :templateid,
316
- :options => [OpenNebulaHelper::XML, OneTemplateHelper::EXTENDED] do
319
+ :options => [OpenNebulaHelper::FORMAT,
320
+ OneTemplateHelper::EXTENDED] do
317
321
  helper.show_resource(args[0], options)
318
322
  end
319
323
 
data/bin/onevrouter CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # -------------------------------------------------------------------------- #
4
- # Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
4
+ # Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
5
5
  # #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
7
7
  # not use this file except in compliance with the License. You may obtain #
@@ -27,9 +27,12 @@ else
27
27
  end
28
28
 
29
29
  if File.directory?(GEMS_LOCATION)
30
- $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
31
- require 'rubygems'
32
- Gem.use_paths(File.realpath(GEMS_LOCATION))
30
+ real_gems_path = File.realpath(GEMS_LOCATION)
31
+ if !defined?(Gem) || Gem.path != [real_gems_path]
32
+ $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
33
+ require 'rubygems'
34
+ Gem.use_paths(real_gems_path)
35
+ end
33
36
  end
34
37
 
35
38
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -79,8 +82,8 @@ CommandParser::CmdParser.new(ARGV) do
79
82
  ########################################################################
80
83
  set :option, CommandParser::OPTIONS + OpenNebulaHelper::CLIENT_OPTIONS
81
84
 
82
- list_options = CLIHelper::OPTIONS
83
- list_options << OpenNebulaHelper::XML
85
+ list_options = CLIHelper::OPTIONS
86
+ list_options += OpenNebulaHelper::FORMAT
84
87
  list_options << OpenNebulaHelper::NUMERIC
85
88
  list_options << OpenNebulaHelper::DESCRIBE
86
89
 
@@ -339,7 +342,7 @@ CommandParser::CmdParser.new(ARGV) do
339
342
  EOT
340
343
 
341
344
  command :show, show_desc, :vrouterid,
342
- :options => [OpenNebulaHelper::XML, OneVMHelper::ALL_TEMPLATE] do
345
+ :options => [OpenNebulaHelper::FORMAT, OneVMHelper::ALL_TEMPLATE] do
343
346
  helper.show_resource(args[0], options)
344
347
  end
345
348
 
data/bin/onezone CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # -------------------------------------------------------------------------- #
4
- # Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
4
+ # Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
5
5
  # #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
7
7
  # not use this file except in compliance with the License. You may obtain #
@@ -27,9 +27,12 @@ else
27
27
  end
28
28
 
29
29
  if File.directory?(GEMS_LOCATION)
30
- $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
31
- require 'rubygems'
32
- Gem.use_paths(File.realpath(GEMS_LOCATION))
30
+ real_gems_path = File.realpath(GEMS_LOCATION)
31
+ if !defined?(Gem) || Gem.path != [real_gems_path]
32
+ $LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
33
+ require 'rubygems'
34
+ Gem.use_paths(real_gems_path)
35
+ end
33
36
  end
34
37
 
35
38
  $LOAD_PATH << RUBY_LIB_LOCATION
@@ -54,7 +57,7 @@ CommandParser::CmdParser.new(ARGV) do
54
57
  }
55
58
 
56
59
  DATABASE = {
57
- :name => 'database',
60
+ :name => 'db',
58
61
  :large => '--db',
59
62
  :description => 'Also sync database'
60
63
  }
@@ -68,8 +71,8 @@ CommandParser::CmdParser.new(ARGV) do
68
71
  ########################################################################
69
72
  set :option, CommandParser::OPTIONS + OpenNebulaHelper::CLIENT_OPTIONS
70
73
 
71
- list_options = CLIHelper::OPTIONS
72
- list_options << OpenNebulaHelper::XML
74
+ list_options = CLIHelper::OPTIONS
75
+ list_options += OpenNebulaHelper::FORMAT
73
76
  list_options << OpenNebulaHelper::NUMERIC
74
77
  list_options << OpenNebulaHelper::DESCRIBE
75
78
 
@@ -208,7 +211,7 @@ CommandParser::CmdParser.new(ARGV) do
208
211
  Shows information for the given Zone
209
212
  EOT
210
213
 
211
- command :show, show_desc, :zoneid, :options => OpenNebulaHelper::XML do
214
+ command :show, show_desc, :zoneid, :options => OpenNebulaHelper::FORMAT do
212
215
  helper.show_resource(args[0], options)
213
216
  end
214
217
 
data/lib/cli_helper.rb CHANGED
@@ -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 #
@@ -181,7 +181,7 @@ module CLIHelper
181
181
  ANSI_YELLOW = "\33[33m"
182
182
 
183
183
  # CLI states
184
- OK_STATES = %w[runn rdy on configured SUCCESS RUNNING]
184
+ OK_STATES = %w[runn rdy on SUCCESS RUNNING]
185
185
  BAD_STATES = %w[fail
186
186
  err
187
187
  error
@@ -189,7 +189,7 @@ module CLIHelper
189
189
  FAILED_DEPLOYING
190
190
  FAILED_UNDEPLOYING
191
191
  FAILED_SCALING]
192
- REGULAR_STATES = %w[pending WARNING]
192
+ REGULAR_STATES = %w[PENDING DEPLOYING CONFIGURING WARNING]
193
193
 
194
194
  # Set state color
195
195
  #
@@ -211,6 +211,17 @@ module CLIHelper
211
211
  end
212
212
  end
213
213
 
214
+ # Get text in green colour
215
+ #
216
+ # @param text [String] String to print
217
+ def self.green(text)
218
+ if $stdout.tty?
219
+ ANSI_GREEN + text + ANSI_RESET
220
+ else
221
+ text
222
+ end
223
+ end
224
+
214
225
  # Print header
215
226
  #
216
227
  # @param str [String] String with header content
@@ -357,14 +368,14 @@ module CLIHelper
357
368
  # @param options [Hash] Object with CLI user options
358
369
  # @param top [Boolean] True to not update columns again
359
370
  def show(data, options = {}, top = false)
371
+ update_columns(options) unless top
372
+
360
373
  if options[:list]
361
374
  @cli_columns = options[:list].collect {|o| o.upcase.to_sym }
362
375
  else
363
376
  @cli_columns = @default_columns
364
377
  end
365
378
 
366
- update_columns(options) unless top
367
-
368
379
  if data.is_a? Hash
369
380
  @data = data
370
381
 
@@ -599,9 +610,7 @@ module CLIHelper
599
610
  end
600
611
  end
601
612
 
602
- if options
603
- filter_data!(res_data, options) if options[:filter]
604
- end
613
+ filter_data!(res_data, options) if options && options[:filter]
605
614
 
606
615
  res_data
607
616
  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 #
@@ -481,9 +481,12 @@ module CommandParser
481
481
  begin
482
482
  rc = comm[:proc].call
483
483
 
484
- if rc.instance_of?(Array)
484
+ if rc.instance_of?(Array) && rc[0] != 0
485
+ STDERR.puts rc[1]
486
+ exit(rc[0])
487
+ elsif rc.instance_of?(Array)
485
488
  puts rc[1]
486
- exit rc.first
489
+ exit(rc[0])
487
490
  else
488
491
  exit(@exit_code || rc)
489
492
  end
@@ -537,7 +540,7 @@ module CommandParser
537
540
  begin
538
541
  @cmdparse.parse!(@args)
539
542
  rescue => e
540
- puts e.message
543
+ STDERR.puts e.message
541
544
  exit -1
542
545
  end
543
546
 
@@ -547,8 +550,8 @@ module CommandParser
547
550
  if rc[0] == 0
548
551
  @options[e[:name].to_sym] = rc[1]
549
552
  else
550
- puts rc[1]
551
- puts "option #{e[:name]}: Parsing error"
553
+ STDERR.puts rc[1]
554
+ STDERR.puts "option #{e[:name]}: Parsing error"
552
555
  exit -1
553
556
  end
554
557
  end
@@ -557,11 +560,11 @@ module CommandParser
557
560
 
558
561
  def check_args!(name, arity, args_format)
559
562
  if @args.length < arity
560
- print "Command #{name} requires "
563
+ STDERR.print "Command #{name} requires "
561
564
  if arity>1
562
- puts "#{args_format.length} parameters to run."
565
+ STDERR.puts "#{args_format.length} parameters to run."
563
566
  else
564
- puts "one parameter to run"
567
+ STDERR.puts "one parameter to run"
565
568
  end
566
569
 
567
570
  print_command_help(name)
@@ -579,11 +582,11 @@ module CommandParser
579
582
  end
580
583
  }.join(' ')
581
584
 
582
- puts "Wrong number of arguments"
585
+ STDERR.puts "Wrong number of arguments"
583
586
  if args_str.empty?
584
- puts "No argument is required"
587
+ STDERR.puts "No argument is required"
585
588
  else
586
- puts "The arguments should be: #{args_str}"
589
+ STDERR.puts "The arguments should be: #{args_str}"
587
590
  end
588
591
  exit -1
589
592
  end
@@ -613,9 +616,9 @@ module CommandParser
613
616
 
614
617
  unless argument
615
618
  if error_msg
616
- puts error_msg
619
+ STDERR.puts error_msg
617
620
  else
618
- puts "command #{name}: argument #{id} must be one of #{format.join(', ')}"
621
+ STDERR.puts "command #{name}: argument #{id} must be one of #{format.join(', ')}"
619
622
  end
620
623
  exit -1
621
624
  end
data/lib/one_helper.rb CHANGED
@@ -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 #
@@ -30,17 +30,19 @@ include OpenNebula
30
30
  module OpenNebulaHelper
31
31
  ONE_VERSION=<<-EOT
32
32
  OpenNebula #{OpenNebula::VERSION}
33
- Copyright 2002-2020, OpenNebula Project, OpenNebula Systems
33
+ Copyright 2002-2021, OpenNebula Project, OpenNebula Systems
34
34
  EOT
35
35
 
36
36
  if ONE_LOCATION
37
- TABLE_CONF_PATH=ONE_LOCATION+"/etc/cli"
38
- VAR_LOCATION=ONE_LOCATION+"/var" if !defined?(VAR_LOCATION)
39
- CLI_ADDONS_LOCATION=ONE_LOCATION+"/lib/ruby/cli/addons"
37
+ TABLE_CONF_PATH = ONE_LOCATION + "/etc/cli"
38
+ VAR_LOCATION = ONE_LOCATION + "/var" if !defined?(VAR_LOCATION)
39
+ CLI_ADDONS_LOCATION = ONE_LOCATION + "/lib/ruby/cli/addons"
40
+ XSD_PATH = ONE_LOCATION + '/share/schemas/xsd'
40
41
  else
41
- TABLE_CONF_PATH="/etc/one/cli"
42
- VAR_LOCATION="/var/lib/one" if !defined?(VAR_LOCATION)
43
- CLI_ADDONS_LOCATION="/usr/lib/one/ruby/cli/addons"
42
+ TABLE_CONF_PATH = "/etc/one/cli"
43
+ VAR_LOCATION = "/var/lib/one" if !defined?(VAR_LOCATION)
44
+ CLI_ADDONS_LOCATION = "/usr/lib/one/ruby/cli/addons"
45
+ XSD_PATH = '/usr/share/one/schemas/xsd'
44
46
  end
45
47
 
46
48
  EDITOR_PATH='/usr/bin/vi'
@@ -55,6 +57,23 @@ EOT
55
57
  :description => "Show the resource in xml format"
56
58
  }
57
59
 
60
+ JSON = {
61
+ :name => 'json',
62
+ :short => '-j',
63
+ :large => '--json',
64
+ :description => 'Show the resource in JSON format',
65
+ :proc => lambda do |_, _|
66
+ require 'json'
67
+ end
68
+ }
69
+
70
+ YAML = {
71
+ :name => 'yaml',
72
+ :short => '-y',
73
+ :large => '--yaml',
74
+ :description => 'Show the resource in YAML format'
75
+ }
76
+
58
77
  NUMERIC={
59
78
  :name => "numeric",
60
79
  :short => "-n",
@@ -428,7 +447,9 @@ EOT
428
447
  UPDATECONF_OPTIONS_VM = TEMPLATE_OPTIONS[6..15] + [TEMPLATE_OPTIONS[2],
429
448
  TEMPLATE_OPTIONS[17], TEMPLATE_OPTIONS[18]]
430
449
 
431
- OPTIONS = XML, EXTENDED, NUMERIC, KILOBYTES
450
+ FORMAT = [XML, JSON, YAML]
451
+
452
+ OPTIONS = FORMAT, EXTENDED, NUMERIC, KILOBYTES
432
453
 
433
454
  class OneHelper
434
455
  attr_accessor :client
@@ -590,12 +611,10 @@ EOT
590
611
  end
591
612
 
592
613
  def print_page(pool, options)
593
- page = nil
614
+ elements = 0
615
+ page = ""
594
616
 
595
617
  if options[:xml]
596
- elements = 0
597
- page = ""
598
-
599
618
  pool.each {|e|
600
619
  elements += 1
601
620
  page << e.to_xml(true) << "\n"
@@ -604,8 +623,15 @@ EOT
604
623
  pname = pool.pool_name
605
624
  ename = pool.element_name
606
625
 
607
- page = pool.to_hash
608
- elems = page["#{pname}"]["#{ename}"]
626
+ if options[:decrypt]
627
+ page = pool.map do |element|
628
+ element.info(true)
629
+ element.to_hash[ename]
630
+ end
631
+ else
632
+ page = pool.to_hash
633
+ elems = page[pname][ename]
634
+ end
609
635
 
610
636
  if elems.class == Array
611
637
  elements = elems.length
@@ -626,7 +652,7 @@ EOT
626
652
  size = $stdout.winsize[0] - 1
627
653
 
628
654
  # ----------- First page, check if pager is needed -------------
629
- rc = pool.get_page(size, 0, false)
655
+ rc = pool.get_page(size, 0, false, options[:state])
630
656
  ps = ""
631
657
 
632
658
  return -1, rc.message if OpenNebula.is_error?(rc)
@@ -654,7 +680,7 @@ EOT
654
680
  options[:no_header] = true
655
681
 
656
682
  loop do
657
- rc = pool.get_page(size, current, false)
683
+ rc = pool.get_page(size, current, false, options[:state])
658
684
 
659
685
  return -1, rc.message if OpenNebula.is_error?(rc)
660
686
 
@@ -677,19 +703,20 @@ EOT
677
703
 
678
704
  stop_pager(ppid)
679
705
  else
680
- array = pool.get_hash
681
- return -1, array.message if OpenNebula.is_error?(array)
706
+ rc = pool.info
682
707
 
683
- rname = self.class.rname
684
- elements = array["#{rname}_POOL"][rname]
708
+ return -1, rc.message if OpenNebula.is_error?(rc)
709
+
710
+ elements, hash = print_page(pool, options)
685
711
 
686
- if options[:ids] && elements
687
- elements.reject! do |element|
712
+ if options[:ids] && elements
713
+ arr = [hash[pool.pool_name][pool.element_name]].flatten
714
+ arr.reject! do |element|
688
715
  !options[:ids].include?(element['ID'].to_i)
689
716
  end
690
717
  end
691
718
 
692
- table.show(array, options)
719
+ table.show(hash, options)
693
720
  end
694
721
 
695
722
  return 0
@@ -705,7 +732,7 @@ EOT
705
732
  size = $stdout.winsize[0] - 1
706
733
 
707
734
  # ----------- First page, check if pager is needed -------------
708
- rc = pool.get_page(size, 0, extended)
735
+ rc = pool.get_page(size, 0, extended, options[:state])
709
736
  ps = ""
710
737
 
711
738
  return -1, rc.message if OpenNebula.is_error?(rc)
@@ -740,7 +767,7 @@ EOT
740
767
  current = size
741
768
 
742
769
  loop do
743
- rc = pool.get_page(size, current, extended)
770
+ rc = pool.get_page(size, current, extended, options[:state])
744
771
 
745
772
  return -1, rc.message if OpenNebula.is_error?(rc)
746
773
 
@@ -779,6 +806,82 @@ EOT
779
806
  return 0
780
807
  end
781
808
 
809
+ #-----------------------------------------------------------------------
810
+ # List pool in JSON format, pagination is used in interactive output
811
+ #-----------------------------------------------------------------------
812
+ def list_pool_format(pool, options, filter_flag)
813
+ extended = options.include?(:extended) && options[:extended]
814
+
815
+ if $stdout.isatty and (!options.key?:no_pager)
816
+ size = $stdout.winsize[0] - 1
817
+
818
+ # ----------- First page, check if pager is needed -------------
819
+ rc = pool.get_page(size, 0, extended, options[:state])
820
+ ps = ""
821
+
822
+ return -1, rc.message if OpenNebula.is_error?(rc)
823
+
824
+ elements = get_format_size(pool, options)
825
+ ppid = -1
826
+
827
+ if elements >= size
828
+ ppid = start_pager
829
+ end
830
+
831
+ yield(pool) if block_given?
832
+
833
+ if elements < size
834
+ return 0
835
+ end
836
+
837
+ if elements < size
838
+ return 0
839
+ elsif !pool.is_paginated?
840
+ stop_pager(ppid)
841
+ return 0
842
+ end
843
+
844
+ # ------- Rest of the pages in the pool, piped to pager --------
845
+ current = size
846
+
847
+ loop do
848
+ rc = pool.get_page(size, current, extended, options[:state])
849
+
850
+ return -1, rc.message if OpenNebula.is_error?(rc)
851
+
852
+ current += size
853
+
854
+ begin
855
+ Process.waitpid(ppid, Process::WNOHANG)
856
+ rescue Errno::ECHILD
857
+ break
858
+ end
859
+
860
+ elements = get_format_size(pool, options)
861
+
862
+ break if elements < size
863
+
864
+ yield(pool) if block_given?
865
+
866
+ $stdout.flush
867
+ end
868
+
869
+ stop_pager(ppid)
870
+ else
871
+ if pool.pool_name == "VM_POOL" && extended
872
+ rc = pool.info_all_extended
873
+ else
874
+ rc = pool.info
875
+ end
876
+
877
+ return -1, rc.message if OpenNebula.is_error?(rc)
878
+
879
+ yield(pool) if block_given?
880
+ end
881
+
882
+ return 0
883
+ end
884
+
782
885
  #-----------------------------------------------------------------------
783
886
  # List pool table in top-like form
784
887
  #-----------------------------------------------------------------------
@@ -807,11 +910,27 @@ EOT
807
910
  filter_flag ||= OpenNebula::Pool::INFO_ALL
808
911
 
809
912
  pool = factory_pool(filter_flag)
913
+ pname = pool.pool_name
914
+ ename = pool.element_name
810
915
 
811
916
  if top
812
917
  return list_pool_top(table, pool, options)
813
918
  elsif options[:xml]
814
919
  return list_pool_xml(pool, options, filter_flag)
920
+ elsif options[:json]
921
+ list_pool_format(pool, options, filter_flag) do |pool|
922
+ hash = check_resource_xsd(pool, pname)
923
+ hash[pname] = check_resource_xsd(hash[pname], ename)
924
+
925
+ puts ::JSON.pretty_generate(hash)
926
+ end
927
+ elsif options[:yaml]
928
+ list_pool_format(pool, options, filter_flag) do |pool|
929
+ hash = check_resource_xsd(pool, pname)
930
+ hash[pname] = check_resource_xsd(hash[pname], ename)
931
+
932
+ puts hash.to_yaml(:indent => 4)
933
+ end
815
934
  else
816
935
  return list_pool_table(table, pool, options, filter_flag)
817
936
  end
@@ -855,6 +974,17 @@ EOT
855
974
 
856
975
  if options[:xml]
857
976
  return 0, resource.to_xml(true)
977
+ elsif options[:json]
978
+ # If body is set, the resource contains a JSON inside
979
+ if options[:body]
980
+ return 0, check_resource_xsd(resource)
981
+ else
982
+ return 0, ::JSON.pretty_generate(
983
+ check_resource_xsd(resource)
984
+ )
985
+ end
986
+ elsif options[:yaml]
987
+ return 0, check_resource_xsd(resource).to_yaml(:indent => 4)
858
988
  else
859
989
  format_resource(resource, options)
860
990
  return 0
@@ -881,7 +1011,7 @@ EOT
881
1011
  rc = perform_action(id,options,verbose,&block)
882
1012
 
883
1013
  unless rc[0]==0
884
- puts rc[1]
1014
+ STDERR.puts rc[1]
885
1015
  exit_code=rc[0]
886
1016
  end
887
1017
  end
@@ -1064,6 +1194,199 @@ EOT
1064
1194
 
1065
1195
  return 0, pool
1066
1196
  end
1197
+
1198
+ def get_format_size(pool, options)
1199
+ if options[:json]
1200
+ ::JSON.pretty_generate(pool.to_hash).split("\n").size
1201
+ elsif options[:yaml]
1202
+ pool.to_hash.to_yaml.split("\n").size
1203
+ else
1204
+ STDERR.puts 'ERROR: Format not found'
1205
+ exit(-1)
1206
+ end
1207
+ end
1208
+
1209
+ ########################################################################
1210
+ # XSD check and fix
1211
+ ########################################################################
1212
+
1213
+ # Check XSD values for a single resource
1214
+ #
1215
+ # @param resource [OpenNebula::Object] Resource to check
1216
+ # @param ename [String] Resource name
1217
+ #
1218
+ # @return [Object] Hash with correct values
1219
+ def check_resource_xsd(resource, ename = nil)
1220
+ hash = resource.to_hash
1221
+ ename = hash.keys.first unless ename
1222
+ xsd = read_xsd(ename)
1223
+
1224
+ return hash unless xsd
1225
+
1226
+ hash[ename] = check_xsd(hash[ename], nil, ename, xsd)
1227
+
1228
+ hash
1229
+ end
1230
+
1231
+ # Read XSD file and parse to XML
1232
+ #
1233
+ # @param ename [String] Element name to read XSD
1234
+ #
1235
+ # @return [Hash] XSD in hash format, nil if not found
1236
+ def read_xsd(ename)
1237
+ require 'active_support/core_ext/hash/conversions'
1238
+
1239
+ # Try GEM directory
1240
+ file = File.expand_path(
1241
+ "../share/schemas/xsd/#{ename.downcase}.xsd",
1242
+ File.dirname(__FILE__)
1243
+ )
1244
+
1245
+ file = "#{XSD_PATH}/#{ename.downcase}.xsd" unless File.exist?(file)
1246
+
1247
+ unless File.exist?(file)
1248
+ STDERR.puts "WARNING: XSD for #{ename} not found, skipping check"
1249
+ return nil
1250
+ end
1251
+
1252
+ hash = Hash.from_xml(Nokogiri::XML(File.read(file)).to_s)
1253
+ hash = hash['schema']['element']
1254
+
1255
+ if hash.keys.include?('complexType')
1256
+ hash['complexType']['sequence']['element']
1257
+ else
1258
+ hash['element']
1259
+ end
1260
+ end
1261
+
1262
+ # Check values XSD
1263
+ #
1264
+ # @param hash [Object] Resource information in hash format
1265
+ # @param elements [Array] Keys to check
1266
+ # @param ename [String] Element name to take XSD
1267
+ # @param xsd [Hash] XSD file content
1268
+ # @param parents [Array] Parent keys of current hash
1269
+ def check_xsd(hash, elements, ename, xsd, parents = [])
1270
+ return unless hash
1271
+
1272
+ if (hash.is_a? Hash) && !hash.empty?
1273
+ hash.map do |ki, vi|
1274
+ vi = [vi].flatten if is_array?(xsd, [ki])
1275
+
1276
+ if (vi.is_a? Hash) && !vi.empty?
1277
+ parents << ki
1278
+
1279
+ vi.map do |kj, vj|
1280
+ parents << kj
1281
+
1282
+ path = (parents + [ki, kj]).uniq
1283
+ vj = [vj].flatten if is_array?(xsd, path)
1284
+
1285
+ hash[ki][kj] = check_xsd(vj,
1286
+ [ki, kj],
1287
+ ename,
1288
+ xsd,
1289
+ parents)
1290
+ end
1291
+
1292
+ parents.clear
1293
+ elsif vi.is_a? Array
1294
+ hash[ki] = check_xsd(vi, [ki], ename, xsd, parents)
1295
+ else
1296
+ hash[ki] = check_xsd(vi, [ki], ename, xsd, parents)
1297
+ end
1298
+ end
1299
+
1300
+ hash
1301
+ elsif hash.is_a? Array
1302
+ ret = []
1303
+
1304
+ hash.each do |v|
1305
+ ret << check_xsd(v, elements, ename, xsd, parents)
1306
+ end
1307
+
1308
+ ret
1309
+ else
1310
+ check_type(hash) do
1311
+ type = get_xsd_path(xsd, elements)
1312
+ type['type'] unless type.nil?
1313
+ end
1314
+ end
1315
+ end
1316
+
1317
+ # Get xsd path value
1318
+ #
1319
+ # @param xsd [Hash] XSD information
1320
+ # @param elements [Array] Path to get
1321
+ #
1322
+ # @return [Hash] Path information
1323
+ def get_xsd_path(xsd, elements)
1324
+ return unless elements
1325
+
1326
+ element = elements.shift
1327
+
1328
+ # Return nil, because is an empty complexType
1329
+ return unless element
1330
+
1331
+ element = [xsd].flatten.find do |v|
1332
+ v['name'] == element || v['ref'] == element
1333
+ end
1334
+
1335
+ # Return nil, because element was not find in XSD
1336
+ return unless element
1337
+
1338
+ if element.keys.include?('complexType') && !elements.empty?
1339
+ if element['complexType']['all']
1340
+ element = element['complexType']['all']['element']
1341
+ else
1342
+ element = element['complexType']['sequence']['element']
1343
+ end
1344
+
1345
+ get_xsd_path(element, elements)
1346
+ else
1347
+ element
1348
+ end
1349
+ end
1350
+
1351
+ # CHeck if current element is an array
1352
+ #
1353
+ # @param xsd [Hash] XSD information
1354
+ # @param elements [Array] Path to check
1355
+ #
1356
+ # @return [Boolean] True if it's an array, false otherwise
1357
+ def is_array?(xsd, elements)
1358
+ max = get_xsd_path(xsd, elements)
1359
+ max = max['maxOccurs'] if max
1360
+
1361
+ max == 'unbounded' || max.to_i > 1
1362
+ end
1363
+
1364
+ # Check XSD type for especific value
1365
+ #
1366
+ # @param value [Object] Value to check
1367
+ #
1368
+ # @return [Object] nil if the type is not correct, value otherwise
1369
+ def check_type(value)
1370
+ type = yield if block_given?
1371
+
1372
+ # If there is no type, return current value
1373
+ return value unless type
1374
+
1375
+ types = %w[string decimal integer boolean date time]
1376
+ type = type.split(':')[1]
1377
+
1378
+ if types.include?(type)
1379
+ # If the current type is different, return string
1380
+ # because this value doesn't respect the type
1381
+ if (value.is_a? Hash) || (value.is_a? Array)
1382
+ ''
1383
+ else
1384
+ value
1385
+ end
1386
+ else
1387
+ value
1388
+ end
1389
+ end
1067
1390
  end
1068
1391
 
1069
1392
  def OpenNebulaHelper.rname_to_id(name, poolname)
@@ -1072,18 +1395,20 @@ EOT
1072
1395
  client=OneHelper.client
1073
1396
 
1074
1397
  pool = case poolname
1075
- when "HOST" then OpenNebula::HostPool.new(client)
1076
- when "HOOK" then OpenNebula::HookPool.new(client)
1077
- when "GROUP" then OpenNebula::GroupPool.new(client)
1078
- when "USER" then OpenNebula::UserPool.new(client)
1079
- when "DATASTORE" then OpenNebula::DatastorePool.new(client)
1080
- when "CLUSTER" then OpenNebula::ClusterPool.new(client)
1081
- when "VNET" then OpenNebula::VirtualNetworkPool.new(client)
1082
- when "IMAGE" then OpenNebula::ImagePool.new(client)
1083
- when "VMTEMPLATE" then OpenNebula::TemplatePool.new(client)
1084
- when "VM" then OpenNebula::VirtualMachinePool.new(client)
1085
- when "ZONE" then OpenNebula::ZonePool.new(client)
1086
- when "MARKETPLACE" then OpenNebula::MarketPlacePool.new(client)
1398
+ when "HOST" then OpenNebula::HostPool.new(client)
1399
+ when "HOOK" then OpenNebula::HookPool.new(client)
1400
+ when "GROUP" then OpenNebula::GroupPool.new(client)
1401
+ when "USER" then OpenNebula::UserPool.new(client)
1402
+ when "DATASTORE" then OpenNebula::DatastorePool.new(client)
1403
+ when "CLUSTER" then OpenNebula::ClusterPool.new(client)
1404
+ when "VNET" then OpenNebula::VirtualNetworkPool.new(client)
1405
+ when "IMAGE" then OpenNebula::ImagePool.new(client)
1406
+ when "VMTEMPLATE" then OpenNebula::TemplatePool.new(client)
1407
+ when "VNTEMPLATES" then OpenNebula::VNTemplatePool.new(client)
1408
+ when "VM" then OpenNebula::VirtualMachinePool.new(client)
1409
+ when "ZONE" then OpenNebula::ZonePool.new(client)
1410
+ when "MARKETPLACE" then OpenNebula::MarketPlacePool.new(client)
1411
+ when "FLOWTEMPLATES" then OpenNebula::ServiceTemplatePool.new(client)
1087
1412
  end
1088
1413
 
1089
1414
  rc = pool.info
@@ -1269,6 +1594,43 @@ EOT
1269
1594
  end
1270
1595
  end
1271
1596
 
1597
+ def OpenNebulaHelper.update_obj(obj, file, plain = false)
1598
+ rc = obj.info(true)
1599
+
1600
+ return rc if OpenNebula.is_error?(rc)
1601
+
1602
+ if file
1603
+ path = file
1604
+ else
1605
+ tmp = Tempfile.new(obj['ID'])
1606
+ path = tmp.path
1607
+
1608
+ tmp.write(yield(obj)) if block_given?
1609
+ tmp.flush
1610
+
1611
+ if ENV['EDITOR']
1612
+ editor_path = ENV['EDITOR']
1613
+ else
1614
+ editor_path = EDITOR_PATH
1615
+ end
1616
+
1617
+ system("#{editor_path} #{path}")
1618
+
1619
+ unless $CHILD_STATUS.exitstatus.zero?
1620
+ STDERR.puts 'Editor not defined'
1621
+ exit(-1)
1622
+ end
1623
+
1624
+ tmp.close
1625
+ end
1626
+
1627
+ if plain
1628
+ obj.update(File.read(path), plain)
1629
+ else
1630
+ obj.update(File.read(path))
1631
+ end
1632
+ end
1633
+
1272
1634
  def OpenNebulaHelper.editor_input(contents=nil)
1273
1635
  require 'tempfile'
1274
1636