opennebula-cli 5.10.5 → 5.11.80.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/oneacct +2 -1
- data/bin/oneacl +2 -1
- data/bin/onecluster +2 -1
- data/bin/onedatastore +2 -1
- data/bin/oneflow +149 -551
- data/bin/oneflow-template +171 -292
- data/bin/onegroup +2 -1
- data/bin/onehook +2 -1
- data/bin/onehost +9 -9
- data/bin/oneimage +2 -1
- data/bin/onemarket +2 -1
- data/bin/onemarketapp +2 -1
- data/bin/onesecgroup +2 -1
- data/bin/oneshowback +2 -1
- data/bin/onetemplate +2 -1
- data/bin/oneuser +2 -1
- data/bin/onevcenter +2 -1
- data/bin/onevdc +2 -1
- data/bin/onevm +88 -16
- data/bin/onevmgroup +2 -1
- data/bin/onevnet +11 -3
- data/bin/onevntemplate +2 -1
- data/bin/onevrouter +2 -1
- data/bin/onezone +2 -1
- data/lib/cli_helper.rb +10 -4
- data/lib/command_parser.rb +32 -13
- data/lib/one_helper.rb +193 -2
- data/lib/one_helper/oneacct_helper.rb +1 -1
- data/lib/one_helper/oneacl_helper.rb +1 -1
- data/lib/one_helper/onecluster_helper.rb +1 -1
- data/lib/one_helper/onedatastore_helper.rb +1 -1
- data/lib/one_helper/oneflow_helper.rb +413 -0
- data/lib/one_helper/oneflowtemplate_helper.rb +306 -0
- data/lib/one_helper/onegroup_helper.rb +1 -1
- data/lib/one_helper/onehook_helper.rb +1 -1
- data/lib/one_helper/onehost_helper.rb +29 -27
- data/lib/one_helper/oneimage_helper.rb +2 -2
- data/lib/one_helper/onemarket_helper.rb +1 -1
- data/lib/one_helper/onemarketapp_helper.rb +1 -1
- data/lib/one_helper/oneprovision_helper.rb +104 -60
- data/lib/one_helper/onequota_helper.rb +1 -1
- data/lib/one_helper/onesecgroup_helper.rb +1 -1
- data/lib/one_helper/onetemplate_helper.rb +9 -180
- data/lib/one_helper/oneuser_helper.rb +1 -1
- data/lib/one_helper/onevcenter_helper.rb +2 -1
- data/lib/one_helper/onevdc_helper.rb +1 -1
- data/lib/one_helper/onevm_helper.rb +11 -6
- data/lib/one_helper/onevmgroup_helper.rb +1 -1
- data/lib/one_helper/onevnet_helper.rb +1 -1
- data/lib/one_helper/onevntemplate_helper.rb +1 -1
- data/lib/one_helper/onevrouter_helper.rb +1 -1
- data/lib/one_helper/onezone_helper.rb +1 -1
- metadata +10 -8
data/bin/onevntemplate
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
3
|
# -------------------------------------------------------------------------- #
|
|
4
|
-
# Copyright 2002-
|
|
4
|
+
# Copyright 2002-2020, 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 #
|
|
@@ -28,6 +28,7 @@ end
|
|
|
28
28
|
|
|
29
29
|
if File.directory?(GEMS_LOCATION)
|
|
30
30
|
Gem.use_paths(GEMS_LOCATION)
|
|
31
|
+
$LOAD_PATH.reject! {|l| l =~ /(vendor|site)_ruby/ }
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
$LOAD_PATH << RUBY_LIB_LOCATION
|
data/bin/onevrouter
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
3
|
# -------------------------------------------------------------------------- #
|
|
4
|
-
# Copyright 2002-
|
|
4
|
+
# Copyright 2002-2020, 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 #
|
|
@@ -28,6 +28,7 @@ end
|
|
|
28
28
|
|
|
29
29
|
if File.directory?(GEMS_LOCATION)
|
|
30
30
|
Gem.use_paths(GEMS_LOCATION)
|
|
31
|
+
$LOAD_PATH.reject! {|l| l =~ /(vendor|site)_ruby/ }
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
$LOAD_PATH << RUBY_LIB_LOCATION
|
data/bin/onezone
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
3
|
# -------------------------------------------------------------------------- #
|
|
4
|
-
# Copyright 2002-
|
|
4
|
+
# Copyright 2002-2020, 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 #
|
|
@@ -28,6 +28,7 @@ end
|
|
|
28
28
|
|
|
29
29
|
if File.directory?(GEMS_LOCATION)
|
|
30
30
|
Gem.use_paths(GEMS_LOCATION)
|
|
31
|
+
$LOAD_PATH.reject! {|l| l =~ /(vendor|site)_ruby/ }
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
$LOAD_PATH << RUBY_LIB_LOCATION
|
data/lib/cli_helper.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2020, 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,9 +181,15 @@ module CLIHelper
|
|
|
181
181
|
ANSI_YELLOW = "\33[33m"
|
|
182
182
|
|
|
183
183
|
# CLI states
|
|
184
|
-
OK_STATES = %w[runn rdy on configured SUCCESS]
|
|
185
|
-
BAD_STATES = %w[fail
|
|
186
|
-
|
|
184
|
+
OK_STATES = %w[runn rdy on configured SUCCESS RUNNING]
|
|
185
|
+
BAD_STATES = %w[fail
|
|
186
|
+
err
|
|
187
|
+
error
|
|
188
|
+
ERROR
|
|
189
|
+
FAILED_DEPLOYING
|
|
190
|
+
FAILED_UNDEPLOYING
|
|
191
|
+
FAILED_SCALING]
|
|
192
|
+
REGULAR_STATES = %w[pending WARNING]
|
|
187
193
|
|
|
188
194
|
# Set state color
|
|
189
195
|
#
|
data/lib/command_parser.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2020, 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 #
|
|
@@ -140,6 +140,7 @@ module CommandParser
|
|
|
140
140
|
# @option options [String] :name
|
|
141
141
|
# @option options [String] :short
|
|
142
142
|
# @option options [String] :large
|
|
143
|
+
# @option options [Boolean] :multiple
|
|
143
144
|
# @option options [String] :description
|
|
144
145
|
# @option options [Class] :format
|
|
145
146
|
# @option options [Block] :proc The block receives the value of the
|
|
@@ -452,7 +453,7 @@ module CommandParser
|
|
|
452
453
|
|
|
453
454
|
if comm.nil?
|
|
454
455
|
print_help
|
|
455
|
-
exit
|
|
456
|
+
exit 0
|
|
456
457
|
end
|
|
457
458
|
|
|
458
459
|
if comm[:deprecated]
|
|
@@ -463,16 +464,27 @@ module CommandParser
|
|
|
463
464
|
parse(extra_options)
|
|
464
465
|
|
|
465
466
|
if comm
|
|
466
|
-
|
|
467
|
+
begin
|
|
468
|
+
@before_proc.call if @before_proc
|
|
469
|
+
rescue StandardError => e
|
|
470
|
+
STDERR.puts e.message
|
|
471
|
+
exit(-1)
|
|
472
|
+
end
|
|
467
473
|
|
|
468
474
|
check_args!(comm_name, comm[:arity], comm[:args_format])
|
|
469
475
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
+
begin
|
|
477
|
+
rc = comm[:proc].call
|
|
478
|
+
|
|
479
|
+
if rc.instance_of?(Array)
|
|
480
|
+
puts rc[1]
|
|
481
|
+
exit rc.first
|
|
482
|
+
else
|
|
483
|
+
exit(@exit_code || rc)
|
|
484
|
+
end
|
|
485
|
+
rescue StandardError => e
|
|
486
|
+
STDERR.puts e.message
|
|
487
|
+
exit(-1)
|
|
476
488
|
end
|
|
477
489
|
end
|
|
478
490
|
end
|
|
@@ -490,21 +502,28 @@ module CommandParser
|
|
|
490
502
|
args = []
|
|
491
503
|
args << e[:short] if e[:short]
|
|
492
504
|
args << e[:large]
|
|
505
|
+
args << e[:multiple] if e[:multiple]
|
|
493
506
|
args << e[:format]
|
|
494
507
|
args << e[:description]
|
|
495
508
|
|
|
496
509
|
opts.on(*args) do |o|
|
|
497
|
-
if e[:proc]
|
|
510
|
+
if e[:proc] && !e[:multiple]
|
|
498
511
|
@options[e[:name].to_sym]=o
|
|
499
512
|
with_proc<<e
|
|
500
513
|
elsif e[:name]=="help"
|
|
501
514
|
print_help
|
|
502
|
-
exit
|
|
515
|
+
exit 0
|
|
503
516
|
elsif e[:name]=="version"
|
|
504
517
|
puts @version
|
|
505
|
-
exit
|
|
506
|
-
|
|
518
|
+
exit 0
|
|
519
|
+
elsif !e[:multiple]
|
|
507
520
|
@options[e[:name].to_sym]=o
|
|
521
|
+
else
|
|
522
|
+
if @options[e[:name].to_sym].nil?
|
|
523
|
+
@options[e[:name].to_sym] = []
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
@options[e[:name].to_sym] << o
|
|
508
527
|
end
|
|
509
528
|
end
|
|
510
529
|
end
|
data/lib/one_helper.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2020, 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,7 +30,7 @@ include OpenNebula
|
|
|
30
30
|
module OpenNebulaHelper
|
|
31
31
|
ONE_VERSION=<<-EOT
|
|
32
32
|
OpenNebula #{OpenNebula::VERSION}
|
|
33
|
-
Copyright 2002-
|
|
33
|
+
Copyright 2002-2020, OpenNebula Project, OpenNebula Systems
|
|
34
34
|
|
|
35
35
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
36
36
|
not use this file except in compliance with the License. You may obtain
|
|
@@ -1696,4 +1696,195 @@ EOT
|
|
|
1696
1696
|
"-"
|
|
1697
1697
|
end
|
|
1698
1698
|
end
|
|
1699
|
+
|
|
1700
|
+
def OpenNebulaHelper.parse_user_inputs(inputs, get_defaults = false)
|
|
1701
|
+
unless get_defaults
|
|
1702
|
+
puts 'There are some parameters that require user input. ' \
|
|
1703
|
+
'Use the string <<EDITOR>> to launch an editor ' \
|
|
1704
|
+
'(e.g. for multi-line inputs)'
|
|
1705
|
+
end
|
|
1706
|
+
|
|
1707
|
+
answers = {}
|
|
1708
|
+
|
|
1709
|
+
inputs.each do |key, val|
|
|
1710
|
+
input_cfg = val.split('|', -1)
|
|
1711
|
+
|
|
1712
|
+
if input_cfg.length < 3
|
|
1713
|
+
STDERR.puts 'Malformed user input. It should have at least 3 '\
|
|
1714
|
+
"parts separated by '|':"
|
|
1715
|
+
STDERR.puts " #{key}: #{val}"
|
|
1716
|
+
exit(-1)
|
|
1717
|
+
end
|
|
1718
|
+
|
|
1719
|
+
mandatory, type, description, params, initial = input_cfg
|
|
1720
|
+
optional = mandatory.strip == 'O'
|
|
1721
|
+
type.strip!
|
|
1722
|
+
description.strip!
|
|
1723
|
+
|
|
1724
|
+
if input_cfg.length > 3
|
|
1725
|
+
if input_cfg.length != 5
|
|
1726
|
+
STDERR.puts 'Malformed user input. It should have 5 parts'\
|
|
1727
|
+
" separated by '|':"
|
|
1728
|
+
STDERR.puts " #{key}: #{val}"
|
|
1729
|
+
exit(-1)
|
|
1730
|
+
end
|
|
1731
|
+
|
|
1732
|
+
params.strip!
|
|
1733
|
+
initial.strip!
|
|
1734
|
+
end
|
|
1735
|
+
|
|
1736
|
+
if get_defaults
|
|
1737
|
+
answers[key]= initial unless mandatory == 'M'
|
|
1738
|
+
next
|
|
1739
|
+
end
|
|
1740
|
+
|
|
1741
|
+
puts " * (#{key}) #{description}"
|
|
1742
|
+
|
|
1743
|
+
header = ' '
|
|
1744
|
+
if !initial.nil? && initial != ''
|
|
1745
|
+
header += "Press enter for default (#{initial}). "
|
|
1746
|
+
end
|
|
1747
|
+
|
|
1748
|
+
case type
|
|
1749
|
+
when 'text', 'text64'
|
|
1750
|
+
print header
|
|
1751
|
+
|
|
1752
|
+
answer = STDIN.readline.chop
|
|
1753
|
+
|
|
1754
|
+
if answer == '<<EDITOR>>'
|
|
1755
|
+
answer = OpenNebulaHelper.editor_input
|
|
1756
|
+
end
|
|
1757
|
+
|
|
1758
|
+
# use default in case it's empty
|
|
1759
|
+
answer = initial if answer.empty?
|
|
1760
|
+
|
|
1761
|
+
if type == 'text64'
|
|
1762
|
+
answer = Base64.encode64(answer).strip.delete("\n")
|
|
1763
|
+
end
|
|
1764
|
+
|
|
1765
|
+
when 'boolean'
|
|
1766
|
+
print header
|
|
1767
|
+
|
|
1768
|
+
answer = STDIN.readline.chop
|
|
1769
|
+
|
|
1770
|
+
# use default in case it's empty
|
|
1771
|
+
answer = initial if answer.empty?
|
|
1772
|
+
|
|
1773
|
+
unless %w[YES NO].include?(answer)
|
|
1774
|
+
STDERR.puts "Invalid boolean '#{answer}'"
|
|
1775
|
+
STDERR.puts 'Boolean has to be YES or NO'
|
|
1776
|
+
exit(-1)
|
|
1777
|
+
end
|
|
1778
|
+
|
|
1779
|
+
when 'password'
|
|
1780
|
+
print header
|
|
1781
|
+
|
|
1782
|
+
answer = OpenNebulaHelper::OneHelper.get_password
|
|
1783
|
+
|
|
1784
|
+
# use default in case it's empty
|
|
1785
|
+
answer = initial if answer.empty?
|
|
1786
|
+
|
|
1787
|
+
when 'number', 'number-float'
|
|
1788
|
+
if type == 'number'
|
|
1789
|
+
header += 'Integer: '
|
|
1790
|
+
exp = INT_EXP
|
|
1791
|
+
else
|
|
1792
|
+
header += 'Float: '
|
|
1793
|
+
exp = FLOAT_EXP
|
|
1794
|
+
end
|
|
1795
|
+
|
|
1796
|
+
begin
|
|
1797
|
+
print header
|
|
1798
|
+
answer = STDIN.readline.chop
|
|
1799
|
+
|
|
1800
|
+
answer = initial if answer == ''
|
|
1801
|
+
noanswer = ((answer == '') && optional)
|
|
1802
|
+
end while !noanswer && (answer =~ exp) == nil
|
|
1803
|
+
|
|
1804
|
+
if noanswer
|
|
1805
|
+
next
|
|
1806
|
+
end
|
|
1807
|
+
|
|
1808
|
+
when 'range', 'range-float'
|
|
1809
|
+
min, max = params.split('..')
|
|
1810
|
+
|
|
1811
|
+
if min.nil? || max.nil?
|
|
1812
|
+
STDERR.puts 'Malformed user input. '\
|
|
1813
|
+
"Parameters should be 'min..max':"
|
|
1814
|
+
STDERR.puts " #{key}: #{val}"
|
|
1815
|
+
exit(-1)
|
|
1816
|
+
end
|
|
1817
|
+
|
|
1818
|
+
if type == 'range'
|
|
1819
|
+
exp = INT_EXP
|
|
1820
|
+
min = min.to_i
|
|
1821
|
+
max = max.to_i
|
|
1822
|
+
|
|
1823
|
+
header += "Integer in the range [#{min}..#{max}]: "
|
|
1824
|
+
else
|
|
1825
|
+
exp = FLOAT_EXP
|
|
1826
|
+
min = min.to_f
|
|
1827
|
+
max = max.to_f
|
|
1828
|
+
|
|
1829
|
+
header += "Float in the range [#{min}..#{max}]: "
|
|
1830
|
+
end
|
|
1831
|
+
|
|
1832
|
+
begin
|
|
1833
|
+
print header
|
|
1834
|
+
answer = STDIN.readline.chop
|
|
1835
|
+
|
|
1836
|
+
answer = initial if answer == ''
|
|
1837
|
+
|
|
1838
|
+
noanswer = (answer == '') && optional
|
|
1839
|
+
end while !noanswer && ((answer =~ exp) == nil ||
|
|
1840
|
+
answer.to_f < min || answer.to_f > max)
|
|
1841
|
+
|
|
1842
|
+
if noanswer
|
|
1843
|
+
next
|
|
1844
|
+
end
|
|
1845
|
+
|
|
1846
|
+
when 'list'
|
|
1847
|
+
options = params.split(',')
|
|
1848
|
+
|
|
1849
|
+
options.each_with_index do |opt, i|
|
|
1850
|
+
puts " #{i} #{opt}"
|
|
1851
|
+
end
|
|
1852
|
+
|
|
1853
|
+
puts
|
|
1854
|
+
|
|
1855
|
+
header += 'Please type the selection number: '
|
|
1856
|
+
|
|
1857
|
+
begin
|
|
1858
|
+
print header
|
|
1859
|
+
answer = STDIN.readline.chop
|
|
1860
|
+
|
|
1861
|
+
if answer == ''
|
|
1862
|
+
answer = initial
|
|
1863
|
+
else
|
|
1864
|
+
answer = options[answer.to_i]
|
|
1865
|
+
end
|
|
1866
|
+
|
|
1867
|
+
noanswer = ((answer == '') && optional)
|
|
1868
|
+
end while !noanswer && !options.include?(answer)
|
|
1869
|
+
|
|
1870
|
+
if noanswer
|
|
1871
|
+
next
|
|
1872
|
+
end
|
|
1873
|
+
|
|
1874
|
+
when 'fixed'
|
|
1875
|
+
puts " Fixed value of (#{initial}). Cannot be changed"
|
|
1876
|
+
answer = initial
|
|
1877
|
+
|
|
1878
|
+
else
|
|
1879
|
+
STDERR.puts 'Wrong type for user input:'
|
|
1880
|
+
STDERR.puts " #{key}: #{val}"
|
|
1881
|
+
exit(-1)
|
|
1882
|
+
end
|
|
1883
|
+
|
|
1884
|
+
answers[key] = answer
|
|
1885
|
+
end
|
|
1886
|
+
|
|
1887
|
+
answers
|
|
1888
|
+
end
|
|
1889
|
+
|
|
1699
1890
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2020, 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-
|
|
2
|
+
# Copyright 2002-2020, 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-
|
|
2
|
+
# Copyright 2002-2020, 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-
|
|
2
|
+
# Copyright 2002-2020, 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 #
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
|
2
|
+
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
|
3
|
+
# #
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
|
6
|
+
# a copy of the License at #
|
|
7
|
+
# #
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
9
|
+
# #
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
13
|
+
# See the License for the specific language governing permissions and #
|
|
14
|
+
# limitations under the License. #
|
|
15
|
+
#--------------------------------------------------------------------------- #
|
|
16
|
+
|
|
17
|
+
require 'one_helper'
|
|
18
|
+
|
|
19
|
+
# Oneflow command helper
|
|
20
|
+
class OneFlowHelper < OpenNebulaHelper::OneHelper
|
|
21
|
+
|
|
22
|
+
# Get client to make request
|
|
23
|
+
#
|
|
24
|
+
# @options [Hash] CLI options
|
|
25
|
+
def client(options)
|
|
26
|
+
Service::Client.new(
|
|
27
|
+
:username => options[:username],
|
|
28
|
+
:password => options[:password],
|
|
29
|
+
:url => options[:server],
|
|
30
|
+
:user_agent => USER_AGENT
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Get service pool table
|
|
35
|
+
def format_service_pool
|
|
36
|
+
# TODO: config file
|
|
37
|
+
CLIHelper::ShowTable.new(nil, self) do
|
|
38
|
+
column :ID, 'ID', :size => 10 do |d|
|
|
39
|
+
d['ID']
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
column :USER, 'Username', :left, :size => 15 do |d|
|
|
43
|
+
d['UNAME']
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
column :GROUP, 'Group', :left, :size => 15 do |d|
|
|
47
|
+
d['GNAME']
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
column :NAME, 'Name', :expand => true, :left => true do |d|
|
|
51
|
+
d['NAME']
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
column :STAT, 'State', :size => 11, :left => true do |d|
|
|
55
|
+
Service.state_str(d['TEMPLATE']['BODY']['state'])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
default :ID, :USER, :GROUP, :NAME, :STAT
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# List service pool
|
|
63
|
+
#
|
|
64
|
+
# @param client [Service::Client] Petition client
|
|
65
|
+
# @param options [Hash] CLI options
|
|
66
|
+
def list_service_pool(client, options)
|
|
67
|
+
response = client.get(RESOURCE_PATH)
|
|
68
|
+
|
|
69
|
+
if CloudClient.is_error?(response)
|
|
70
|
+
[response.code.to_i, response.to_s]
|
|
71
|
+
else
|
|
72
|
+
array_list = JSON.parse(response.body)
|
|
73
|
+
array_list = array_list['DOCUMENT_POOL']['DOCUMENT']
|
|
74
|
+
|
|
75
|
+
array_list = [] if array_list.nil?
|
|
76
|
+
|
|
77
|
+
unless options.key? :done
|
|
78
|
+
# remove from list flows in DONE state
|
|
79
|
+
array_list.reject! do |value|
|
|
80
|
+
value['TEMPLATE']['BODY']['state'] == 5
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
if options[:json]
|
|
85
|
+
if array_list.empty?
|
|
86
|
+
0
|
|
87
|
+
else
|
|
88
|
+
[0, JSON.pretty_generate(array_list)]
|
|
89
|
+
end
|
|
90
|
+
else
|
|
91
|
+
format_service_pool.show(array_list)
|
|
92
|
+
|
|
93
|
+
0
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# List service pool continiously
|
|
99
|
+
#
|
|
100
|
+
# @param client [Service::Client] Petition client
|
|
101
|
+
# @param options [Hash] CLI options
|
|
102
|
+
def top_service_pool(client, options)
|
|
103
|
+
# TODO: make default delay configurable
|
|
104
|
+
options[:delay] ? delay = options[:delay] : delay = 4
|
|
105
|
+
|
|
106
|
+
begin
|
|
107
|
+
loop do
|
|
108
|
+
CLIHelper.scr_cls
|
|
109
|
+
CLIHelper.scr_move(0, 0)
|
|
110
|
+
|
|
111
|
+
list_service_pool(client, options)
|
|
112
|
+
|
|
113
|
+
sleep delay
|
|
114
|
+
end
|
|
115
|
+
rescue StandardError => e
|
|
116
|
+
STDERR.puts e.message
|
|
117
|
+
exit(-1)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
0
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Show service detailed information
|
|
124
|
+
#
|
|
125
|
+
# @param client [Service::Client] Petition client
|
|
126
|
+
# @param service [Integer] Service ID
|
|
127
|
+
# @param options [Hash] CLI options
|
|
128
|
+
def format_resource(client, service, options)
|
|
129
|
+
response = client.get("#{RESOURCE_PATH}/#{service}")
|
|
130
|
+
|
|
131
|
+
if CloudClient.is_error?(response)
|
|
132
|
+
[response.code.to_i, response.to_s]
|
|
133
|
+
else
|
|
134
|
+
if options[:json]
|
|
135
|
+
[0, response.body]
|
|
136
|
+
else
|
|
137
|
+
str_h1 = '%-80s'
|
|
138
|
+
document = JSON.parse(response.body)['DOCUMENT']
|
|
139
|
+
template = document['TEMPLATE']['BODY']
|
|
140
|
+
|
|
141
|
+
CLIHelper.print_header(
|
|
142
|
+
str_h1 % "SERVICE #{document['ID']} INFORMATION"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
print_service_info(document)
|
|
146
|
+
|
|
147
|
+
print_roles_info(template['roles'])
|
|
148
|
+
|
|
149
|
+
return 0 unless template['log']
|
|
150
|
+
|
|
151
|
+
CLIHelper.print_header(str_h1 % 'LOG MESSAGES', false)
|
|
152
|
+
|
|
153
|
+
template['log'].each do |log|
|
|
154
|
+
t = Time.at(log['timestamp']).strftime('%m/%d/%y %H:%M')
|
|
155
|
+
puts "#{t} [#{log['severity']}] #{log['message']}"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
0
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Get policy adjust information in str format
|
|
164
|
+
#
|
|
165
|
+
# @param policy [Hash] Policy information
|
|
166
|
+
def self.adjust_str(policy)
|
|
167
|
+
policy['adjust'].to_i >= 0 ? sign = '+' : sign = '-'
|
|
168
|
+
adjust = policy['adjust'].to_i.abs
|
|
169
|
+
|
|
170
|
+
case policy['type']
|
|
171
|
+
when 'CARDINALITY'
|
|
172
|
+
"= #{adjust}"
|
|
173
|
+
when 'PERCENTAGE_CHANGE'
|
|
174
|
+
st = "#{sign} #{adjust} %"
|
|
175
|
+
|
|
176
|
+
if policy['min_adjust_step']
|
|
177
|
+
st << " (#{policy['min_adjust_step']})"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
st
|
|
181
|
+
else
|
|
182
|
+
"#{sign} #{adjust}"
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
private
|
|
187
|
+
|
|
188
|
+
# Get nodes pool table
|
|
189
|
+
def format_node_pool
|
|
190
|
+
# TODO: config file
|
|
191
|
+
CLIHelper::ShowTable.new(nil, self) do
|
|
192
|
+
column :VM_ID,
|
|
193
|
+
'ONE identifier for Virtual Machine',
|
|
194
|
+
:size => 6 do |d|
|
|
195
|
+
st = ''
|
|
196
|
+
|
|
197
|
+
if d['scale_up']
|
|
198
|
+
st << '\u2191 '
|
|
199
|
+
elsif d['disposed']
|
|
200
|
+
st << '\u2193 '
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
if d['vm_info'].nil?
|
|
204
|
+
st << d['deploy_id'].to_s
|
|
205
|
+
else
|
|
206
|
+
st << d['vm_info']['VM']['ID']
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
st
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
column :NAME,
|
|
213
|
+
'Name of the Virtual Machine',
|
|
214
|
+
:left,
|
|
215
|
+
:size => 24 do |d|
|
|
216
|
+
if !d['vm_info'].nil?
|
|
217
|
+
if d['vm_info']['VM']['RESCHED'] == '1'
|
|
218
|
+
"*#{d['NAME']}"
|
|
219
|
+
else
|
|
220
|
+
d['vm_info']['VM']['NAME']
|
|
221
|
+
end
|
|
222
|
+
else
|
|
223
|
+
''
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
column :USER,
|
|
228
|
+
'Username of the Virtual Machine owner',
|
|
229
|
+
:left,
|
|
230
|
+
:size => 15 do |d|
|
|
231
|
+
if !d['vm_info'].nil?
|
|
232
|
+
d['vm_info']['VM']['UNAME']
|
|
233
|
+
else
|
|
234
|
+
''
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
column :GROUP,
|
|
239
|
+
'Group of the Virtual Machine',
|
|
240
|
+
:left,
|
|
241
|
+
:size => 15 do |d|
|
|
242
|
+
if !d['vm_info'].nil?
|
|
243
|
+
d['vm_info']['VM']['GNAME']
|
|
244
|
+
else
|
|
245
|
+
''
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
default :VM_ID, :NAME, :USER, :GROUP
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Print service information
|
|
254
|
+
#
|
|
255
|
+
# @param document [Hash] Service document information
|
|
256
|
+
def print_service_info(document)
|
|
257
|
+
str = '%-20s: %-20s'
|
|
258
|
+
str_h1 = '%-80s'
|
|
259
|
+
template = document['TEMPLATE']['BODY']
|
|
260
|
+
|
|
261
|
+
puts Kernel.format(str, 'ID', document['ID'])
|
|
262
|
+
puts Kernel.format(str, 'NAME', document['NAME'])
|
|
263
|
+
puts Kernel.format(str, 'USER', document['UNAME'])
|
|
264
|
+
puts Kernel.format(str, 'GROUP', document['GNAME'])
|
|
265
|
+
|
|
266
|
+
puts Kernel.format(str, 'STRATEGY', template['deployment'])
|
|
267
|
+
puts Kernel.format(str,
|
|
268
|
+
'SERVICE STATE',
|
|
269
|
+
Service.state_str(template['state']))
|
|
270
|
+
|
|
271
|
+
if template['shutdown_action']
|
|
272
|
+
puts Kernel.format(str, 'SHUTDOWN', template['shutdown_action'])
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
puts
|
|
276
|
+
|
|
277
|
+
CLIHelper.print_header(str_h1 % 'PERMISSIONS', false)
|
|
278
|
+
|
|
279
|
+
%w[OWNER GROUP OTHER].each do |e|
|
|
280
|
+
mask = '---'
|
|
281
|
+
permissions_hash = document['PERMISSIONS']
|
|
282
|
+
mask[0] = 'u' if permissions_hash["#{e}_U"] == '1'
|
|
283
|
+
mask[1] = 'm' if permissions_hash["#{e}_M"] == '1'
|
|
284
|
+
mask[2] = 'a' if permissions_hash["#{e}_A"] == '1'
|
|
285
|
+
|
|
286
|
+
puts Kernel.format(str, e, mask)
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
puts
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# Print service roles information
|
|
293
|
+
#
|
|
294
|
+
# @param roles [Array] Service roles information
|
|
295
|
+
def print_roles_info(roles)
|
|
296
|
+
str = '%-20s: %-20s'
|
|
297
|
+
|
|
298
|
+
roles.each do |role|
|
|
299
|
+
CLIHelper.print_header("ROLE #{role['name']}", false)
|
|
300
|
+
|
|
301
|
+
puts Kernel.format(str,
|
|
302
|
+
'ROLE STATE',
|
|
303
|
+
Role.state_str(role['state']))
|
|
304
|
+
|
|
305
|
+
if role['parents']
|
|
306
|
+
puts Kernel.format(str,
|
|
307
|
+
'PARENTS',
|
|
308
|
+
role['parents'].join(', '))
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
puts Kernel.format(str, 'VM TEMPLATE', role['vm_template'])
|
|
312
|
+
puts Kernel.format(str, 'CARDINALITY', role['cardinality'])
|
|
313
|
+
|
|
314
|
+
if role['min_vms']
|
|
315
|
+
puts Kernel.format(str, 'MIN VMS', role['min_vms'])
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
if role['max_vms']
|
|
319
|
+
puts Kernel.format(str, 'MAX VMS', role['max_vms'])
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
if role['coolddown']
|
|
323
|
+
puts Kernel.format(str, 'COOLDOWN', "#{role['cooldown']}s")
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
if role['shutdown_action']
|
|
327
|
+
puts Kernel.format(str, 'SHUTDOWN', role['shutdown_action'])
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
if role['elasticity_policies'] &&
|
|
331
|
+
!role['elasticity_policies'].empty?
|
|
332
|
+
print_elasticity_info(role)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
if role['scheduled_policies'] &&
|
|
336
|
+
!role['scheduled_policies'].empty?
|
|
337
|
+
print_scheduled_info(role)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
puts
|
|
341
|
+
CLIHelper.print_header('NODES INFORMATION', false)
|
|
342
|
+
|
|
343
|
+
format_node_pool.show(role['nodes'])
|
|
344
|
+
puts
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Print role elasticity info
|
|
349
|
+
#
|
|
350
|
+
# @param role [OpenNebula::Role] Role information
|
|
351
|
+
def print_elasticity_info(role)
|
|
352
|
+
puts
|
|
353
|
+
CLIHelper.print_header('ROLE ELASTICITY', false)
|
|
354
|
+
|
|
355
|
+
CLIHelper::ShowTable.new(nil, self) do
|
|
356
|
+
column :ADJUST, '', :left, :size => 12 do |d|
|
|
357
|
+
OneFlowHelper.adjust_str(d)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
column :EXPRESSION, '', :left, :size => 48 do |d|
|
|
361
|
+
if !d['expression_evaluated'].nil?
|
|
362
|
+
d['expression_evaluated']
|
|
363
|
+
else
|
|
364
|
+
d['expression']
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
column :EVALS, '', :right, :size => 5 do |d|
|
|
369
|
+
if d['period_number']
|
|
370
|
+
"#{d['true_evals'].to_i}/"\
|
|
371
|
+
"#{d['period_number']}"
|
|
372
|
+
else
|
|
373
|
+
'-'
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
column :PERIOD, '', :size => 6 do |d|
|
|
378
|
+
d['period'] ? "#{d['period']}s" : '-'
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
column :COOL, '', :size => 5 do |d|
|
|
382
|
+
d['cooldown'] ? "#{d['cooldown']}s" : '-'
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
default :ADJUST, :EXPRESSION, :EVALS, :PERIOD, :COOL
|
|
386
|
+
end.show([role['elasticity_policies']].flatten, {})
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# Print role schedule info
|
|
390
|
+
#
|
|
391
|
+
# @param role [OpenNebula::Role] Role information
|
|
392
|
+
def print_scheduled_info(role)
|
|
393
|
+
puts
|
|
394
|
+
CLIHelper.print_header('ROLE ELASTICITY SCHEDULE', false)
|
|
395
|
+
|
|
396
|
+
CLIHelper::ShowTable.new(nil, self) do
|
|
397
|
+
column :ADJUST, '', :left, :size => 12 do |d|
|
|
398
|
+
OneFlowHelper.adjust_str(d)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
column :TIME, '', :left, :size => 67 do |d|
|
|
402
|
+
if d['start_time']
|
|
403
|
+
Time.parse(d['start_time']).to_s
|
|
404
|
+
else
|
|
405
|
+
d['recurrence']
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
default :ADJUST, :TIME
|
|
410
|
+
end.show([role['scheduled_policies']].flatten, {})
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
end
|