magellan-cli 0.2.17 → 0.2.18
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/Gemfile +2 -0
- data/Gemfile.lock +17 -1
- data/README.md +19 -0
- data/Rakefile +7 -0
- data/bin/magellan-cli +1 -12
- data/lib/magellan/cli/base.rb +100 -4
- data/lib/magellan/cli/command.rb +62 -22
- data/lib/magellan/cli/http.rb +9 -1
- data/lib/magellan/cli/login.rb +2 -0
- data/lib/magellan/cli/reference_generator.rb +100 -0
- data/lib/magellan/cli/resources/base.rb +18 -11
- data/lib/magellan/cli/resources/client_version.rb +3 -3
- data/lib/magellan/cli/resources/cloudsql.rb +5 -5
- data/lib/magellan/cli/resources/container.rb +1 -1
- data/lib/magellan/cli/resources/image.rb +1 -1
- data/lib/magellan/cli/resources/organization.rb +4 -3
- data/lib/magellan/cli/resources/project.rb +4 -4
- data/lib/magellan/cli/resources/stage.rb +14 -14
- data/lib/magellan/cli/resources/team.rb +5 -5
- data/lib/magellan/cli/resources/transaction_router.rb +3 -3
- data/lib/magellan/cli/resources/worker.rb +6 -6
- data/lib/magellan/cli/version.rb +1 -1
- data/lib/magellan/cli.rb +1 -0
- data/spec/magellan/cli/command_spec.rb +34 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb40bd948d572f7f0a642dc9b3baff058c112eb4
|
4
|
+
data.tar.gz: 50c8e29d10da813eddf77cf192ab9bb7e3782bf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9d3a89a666fe6454a1c1bd1f1ccb65b7a6daa9f334ab253d86f65cae27a5aff4e35586e9a78abed6b7d457c794a5abe06cc5b51552143f02f9047fd0a22f7c2
|
7
|
+
data.tar.gz: d3db854dcefaa6d1a7b6bbc62b5566a355a473496331166e5ad1c49ae85ed0689672d07c707e40e1d1819cd117af02df8968c760e8a686f954901f62bca5e08e
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
magellan-cli (0.2.
|
4
|
+
magellan-cli (0.2.18)
|
5
5
|
activesupport (~> 4.1.4)
|
6
6
|
groovenauts-thor
|
7
7
|
httpclient (~> 2.5)
|
@@ -17,7 +17,15 @@ GEM
|
|
17
17
|
minitest (~> 5.1)
|
18
18
|
thread_safe (~> 0.1)
|
19
19
|
tzinfo (~> 1.1)
|
20
|
+
binding_of_caller (0.7.2)
|
21
|
+
debug_inspector (>= 0.0.1)
|
22
|
+
byebug (2.7.0)
|
23
|
+
columnize (~> 0.3)
|
24
|
+
debugger-linecache (~> 1.2)
|
20
25
|
coderay (1.1.0)
|
26
|
+
columnize (0.9.0)
|
27
|
+
debug_inspector (0.0.2)
|
28
|
+
debugger-linecache (1.2.0)
|
21
29
|
diff-lcs (1.2.5)
|
22
30
|
groovenauts-thor (0.19.1)
|
23
31
|
httpclient (2.6.0.1)
|
@@ -32,6 +40,12 @@ GEM
|
|
32
40
|
coderay (~> 1.0)
|
33
41
|
method_source (~> 0.8)
|
34
42
|
slop (~> 3.4)
|
43
|
+
pry-byebug (1.3.2)
|
44
|
+
byebug (~> 2.7)
|
45
|
+
pry (~> 0.9.12)
|
46
|
+
pry-stack_explorer (0.4.9.1)
|
47
|
+
binding_of_caller (>= 0.7)
|
48
|
+
pry (>= 0.9.11)
|
35
49
|
rake (10.3.2)
|
36
50
|
rspec (3.0.0)
|
37
51
|
rspec-core (~> 3.0.0)
|
@@ -58,5 +72,7 @@ DEPENDENCIES
|
|
58
72
|
bundler (~> 1.6)
|
59
73
|
magellan-cli!
|
60
74
|
pry
|
75
|
+
pry-byebug
|
76
|
+
pry-stack_explorer
|
61
77
|
rake (~> 10.0)
|
62
78
|
rspec
|
data/README.md
CHANGED
@@ -18,6 +18,25 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install magellan-cli
|
20
20
|
|
21
|
+
|
22
|
+
## generate reference pages
|
23
|
+
|
24
|
+
```
|
25
|
+
DEST=/path/to/magellan-devcenter.github.io bundle exec rake reference
|
26
|
+
```
|
27
|
+
|
28
|
+
then
|
29
|
+
|
30
|
+
```
|
31
|
+
cd /path/to/magellan-devcenter.github.io
|
32
|
+
bundle exec jekyll serve
|
33
|
+
```
|
34
|
+
|
35
|
+
open http://localhost:4000/reference/magellan-cli
|
36
|
+
|
37
|
+
After check the pages, you can commit the .md files to magellan-devcenter.github.io repogitory.
|
38
|
+
|
39
|
+
|
21
40
|
## Usage
|
22
41
|
|
23
42
|
### All-in-one patterns
|
data/Rakefile
CHANGED
data/bin/magellan-cli
CHANGED
@@ -2,15 +2,4 @@
|
|
2
2
|
|
3
3
|
require 'magellan/cli'
|
4
4
|
|
5
|
-
|
6
|
-
Magellan::Cli::Command.start(ARGV)
|
7
|
-
rescue Magellan::Cli::Error => e
|
8
|
-
$stderr.puts("\e[31m#{e.message}\e[0m")
|
9
|
-
exit(1)
|
10
|
-
rescue => e
|
11
|
-
verbose = ARGV.include?("-V") || ARGV.include?("--verbose")
|
12
|
-
msg = "\e[31m[#{e.class}] #{e.message}\e[0m"
|
13
|
-
msg << "\n " << e.backtrace.join("\n ") if verbose
|
14
|
-
$stderr.puts(msg)
|
15
|
-
exit(1)
|
16
|
-
end
|
5
|
+
Magellan::Cli::Command.start(ARGV)
|
data/lib/magellan/cli/base.rb
CHANGED
@@ -7,6 +7,7 @@ module Magellan
|
|
7
7
|
class Base < Thor
|
8
8
|
class_option :verbose, type: :boolean, aliases: "-V"
|
9
9
|
class_option :dryrun , type: :boolean, aliases: "-D"
|
10
|
+
class_option :version, type: :boolean, aliases: "-v"
|
10
11
|
|
11
12
|
no_commands do
|
12
13
|
|
@@ -29,17 +30,17 @@ module Magellan
|
|
29
30
|
end
|
30
31
|
|
31
32
|
def verbose(msg)
|
32
|
-
|
33
|
+
self.class.verbose(msg) if verbose?
|
33
34
|
end
|
34
35
|
|
35
36
|
def info(msg)
|
36
|
-
|
37
|
+
self.class.info(msg)
|
37
38
|
end
|
38
39
|
def success(msg)
|
39
|
-
|
40
|
+
self.class.success(msg)
|
40
41
|
end
|
41
42
|
def error(msg)
|
42
|
-
|
43
|
+
self.class.error(msg)
|
43
44
|
end
|
44
45
|
|
45
46
|
def fatal(msg)
|
@@ -48,6 +49,101 @@ module Magellan
|
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
52
|
+
class << self
|
53
|
+
def puts_with_color(color_no, msg)
|
54
|
+
$stderr.puts("\e[#{color_no}m#{msg}\e[0m")
|
55
|
+
end
|
56
|
+
|
57
|
+
def verbose(msg, flag = true)
|
58
|
+
puts_with_color(34, msg) if flag
|
59
|
+
end
|
60
|
+
def info(msg)
|
61
|
+
puts_with_color(0, msg)
|
62
|
+
end
|
63
|
+
def success(msg)
|
64
|
+
puts_with_color(32, msg)
|
65
|
+
end
|
66
|
+
def error(msg)
|
67
|
+
puts_with_color(31, msg)
|
68
|
+
end
|
69
|
+
|
70
|
+
def sorted_commands(all = true)
|
71
|
+
cmd_hash = all_commands.dup
|
72
|
+
Thor::Util.thor_classes_in(self).each do |klass|
|
73
|
+
cmd_hash.update(klass.commands)
|
74
|
+
end
|
75
|
+
if order = self.const_get(:COMMAND_ORDER) rescue nil
|
76
|
+
result = order.map{|i| cmd_hash[i]}
|
77
|
+
result += (cmd_hash.keys - order).map{|i| cmd_hash[i]}
|
78
|
+
else
|
79
|
+
result = cmd_hash.values
|
80
|
+
end
|
81
|
+
if idx = result.index{|cmd| cmd.name == "help" }
|
82
|
+
h = result.delete_at(idx)
|
83
|
+
result << h
|
84
|
+
end
|
85
|
+
return result
|
86
|
+
end
|
87
|
+
|
88
|
+
def sorted_printable_commands(all = true, subcommand = false)
|
89
|
+
list = printable_commands(all, subcommand)
|
90
|
+
Thor::Util.thor_classes_in(self).each do |klass|
|
91
|
+
list += klass.printable_commands(false)
|
92
|
+
end
|
93
|
+
order = self.const_get(:COMMAND_ORDER) rescue nil
|
94
|
+
if order
|
95
|
+
orig = list
|
96
|
+
list = order.map do |ptn|
|
97
|
+
idx = orig.index{|t| t.first =~ /\b#{ptn}\b/}
|
98
|
+
raise "#{ptn} not found" unless idx
|
99
|
+
orig.delete_at(idx)
|
100
|
+
end
|
101
|
+
list += orig # add items not in COMMAND_ORDER
|
102
|
+
end
|
103
|
+
# # don't sort in alphabetical order
|
104
|
+
# list.sort! { |a, b| a[0] <=> b[0] }
|
105
|
+
|
106
|
+
# move help to the end of list
|
107
|
+
if idx = list.index{|t| t.first =~ /\bhelp\b/ }
|
108
|
+
h = list.delete_at(idx)
|
109
|
+
list << h
|
110
|
+
end
|
111
|
+
return list
|
112
|
+
end
|
113
|
+
|
114
|
+
# overwrite Thor.help method
|
115
|
+
def help(shell, subcommand = false)
|
116
|
+
if defined?(@package_name) && @package_name
|
117
|
+
shell.say "#{@package_name} commands:"
|
118
|
+
else
|
119
|
+
shell.say "Commands:"
|
120
|
+
end
|
121
|
+
|
122
|
+
shell.print_table(sorted_printable_commands(true, subcommand), :indent => 2, :truncate => true)
|
123
|
+
shell.say
|
124
|
+
class_options_help(shell)
|
125
|
+
end
|
126
|
+
|
127
|
+
# override Thor.command_help
|
128
|
+
def command_help(shell, command_name)
|
129
|
+
meth = normalize_command_name(command_name)
|
130
|
+
command = all_commands[meth]
|
131
|
+
handle_no_command_error(meth) unless command
|
132
|
+
|
133
|
+
shell.say "Usage:"
|
134
|
+
shell.say " #{banner(command)}"
|
135
|
+
shell.say
|
136
|
+
class_options_help(shell, nil => command.options.map { |_, o| o })
|
137
|
+
if command.long_description
|
138
|
+
shell.say "Description:"
|
139
|
+
shell.print_wrapped(command.long_description, :indent => 2)
|
140
|
+
else
|
141
|
+
shell.say command.description
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
51
147
|
end
|
52
148
|
end
|
53
149
|
end
|
data/lib/magellan/cli/command.rb
CHANGED
@@ -6,40 +6,80 @@ require 'active_support/core_ext/string/inflections'
|
|
6
6
|
module Magellan
|
7
7
|
module Cli
|
8
8
|
class Command < Base
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# override Thor::Base.start method
|
12
|
+
def start(given_args = ARGV, config = {})
|
13
|
+
# class_options verbose and version are defined in Magellan::Cli::Base
|
14
|
+
if ARGV.include?("-v") || ARGV.include?("--version")
|
15
|
+
info(File.basename($0) << " " << Magellan::Cli::VERSION)
|
16
|
+
end
|
17
|
+
begin
|
18
|
+
super(given_args, config)
|
19
|
+
rescue Magellan::Cli::Error => e
|
20
|
+
error(e.message)
|
21
|
+
exit(1)
|
22
|
+
rescue => e
|
23
|
+
error("[#{e.class}] #{e.message}")
|
24
|
+
verbose(" " << e.backtrace.join("\n "), ARGV.include?("-V") || ARGV.include?("--verbose"))
|
25
|
+
exit(1)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# overwrite Magellan::Cli::Base.help method
|
30
|
+
def help(shell, subcommand = false)
|
31
|
+
super(shell, subcommand)
|
32
|
+
|
33
|
+
shell.say
|
34
|
+
shell.say "RESOURCES:"
|
35
|
+
shell.say " " << RESOURCES.keys.join(", ")
|
36
|
+
shell.say " type `#{File.basename($0)} help RESOURCE` for more detail"
|
37
|
+
shell.say
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
RESOURCES =\
|
9
42
|
{
|
10
|
-
"
|
11
|
-
"
|
12
|
-
"
|
13
|
-
"
|
14
|
-
"
|
15
|
-
#"
|
16
|
-
"
|
17
|
-
"
|
18
|
-
"
|
19
|
-
"
|
20
|
-
}
|
21
|
-
|
43
|
+
"Organization" => "organization",
|
44
|
+
"Team" => "team",
|
45
|
+
"Project" => "project",
|
46
|
+
"Stage" => "stage",
|
47
|
+
"ClientVersion" => "client_version",
|
48
|
+
#"TransactionRouter" => "tr",
|
49
|
+
"Worker" => "worker",
|
50
|
+
"Image" => "image",
|
51
|
+
"Container" => "container",
|
52
|
+
"Cloudsql" => "cloudsql",
|
53
|
+
}
|
54
|
+
|
55
|
+
RESOURCES.each do |classname, name|
|
56
|
+
desc "#{name} SUBCOMMAND ...ARGS", "manage #{name.pluralize}"
|
22
57
|
subcommand name, ::Magellan::Cli::Resources.const_get(classname)
|
23
58
|
end
|
24
59
|
|
60
|
+
COMMAND_ORDER = %w[login] + RESOURCES.values
|
61
|
+
|
25
62
|
#desc "direct SUBCOMMAND ...ARGS", "send request directly"
|
26
63
|
#subcommand "direct", ::Magellan::Cli::Direct
|
27
64
|
|
28
|
-
desc "login", "login to
|
65
|
+
desc "login", "login to the Magellan server"
|
66
|
+
method_option :email, aliases: "-e", desc: "email address for login"
|
67
|
+
method_option :password, aliases: "-p", desc: "password for login"
|
29
68
|
def login
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
69
|
+
unless email = options[:email]
|
70
|
+
print "email: "
|
71
|
+
email = STDIN.gets.strip
|
72
|
+
end
|
73
|
+
|
74
|
+
unless password = options[:password]
|
75
|
+
print "password: "
|
76
|
+
password = STDIN.noecho(&:gets).chomp
|
77
|
+
puts ""
|
78
|
+
end
|
35
79
|
|
36
80
|
Magellan::Cli::Http.new.login!(email, password)
|
37
81
|
end
|
38
82
|
|
39
|
-
desc "version", "show version"
|
40
|
-
def version
|
41
|
-
$stdout.puts Magellan::Cli::VERSION
|
42
|
-
end
|
43
83
|
end
|
44
84
|
end
|
45
85
|
end
|
data/lib/magellan/cli/http.rb
CHANGED
@@ -19,7 +19,15 @@ module Magellan
|
|
19
19
|
|
20
20
|
def access_api
|
21
21
|
cli = Cli::Login.new
|
22
|
-
|
22
|
+
if block_given?
|
23
|
+
auth = cli.login_auth
|
24
|
+
if auth.nil? || auth.empty?
|
25
|
+
raise Magellan::Cli::Error, "Not logined yet. type `#{File.basename($0)} login`."
|
26
|
+
end
|
27
|
+
return yield(cli)
|
28
|
+
else
|
29
|
+
return success("OK")
|
30
|
+
end
|
23
31
|
end
|
24
32
|
|
25
33
|
def check_response(res)
|
data/lib/magellan/cli/login.rb
CHANGED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'magellan/cli'
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Magellan
|
6
|
+
module Cli
|
7
|
+
class ReferenceGenerator
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@dest = options[:dest] || "doc"
|
11
|
+
@subdir = options[:subdir] || "."
|
12
|
+
@io = $stdout
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
@shell = Thor::Shell::Basic.new
|
17
|
+
change_global_var_temporarily(["$PROGRAM_NAME", "magellan-cli"]) do
|
18
|
+
process(Magellan::Cli::Command, "index.md")
|
19
|
+
Magellan::Cli::Command::RESOURCES.each do |class_name, res_name|
|
20
|
+
klass = Magellan::Cli::Resources.const_get(class_name)
|
21
|
+
process(klass, "#{res_name}.md", res_name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def change_global_var_temporarily(*tuples, &block)
|
27
|
+
if tuples.empty?
|
28
|
+
block.call if block
|
29
|
+
else
|
30
|
+
gvar_name, value = *tuples.shift
|
31
|
+
backup = eval(gvar_name)
|
32
|
+
begin
|
33
|
+
eval("#{gvar_name} = value")
|
34
|
+
change_global_var_temporarily(*tuples, &block)
|
35
|
+
ensure
|
36
|
+
eval("#{gvar_name} = backup")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def process(klass, filename, res_name = nil)
|
42
|
+
path = File.expand_path(File.join(@subdir, filename), @dest)
|
43
|
+
FileUtils.mkdir_p(File.dirname(path))
|
44
|
+
instance = klass.new
|
45
|
+
open(path, "w") do |f|
|
46
|
+
f.puts "---"
|
47
|
+
f.puts "layout: index"
|
48
|
+
f.puts %!breadcrumb: <a href="/">Top</a> / <a href="/reference">Reference</a> / <a href="/reference/magellan-cli">magellan-cli</a> / magellan-cli #{res_name}!
|
49
|
+
f.puts "---"
|
50
|
+
f.puts
|
51
|
+
|
52
|
+
f.puts "## Commands"
|
53
|
+
f.puts
|
54
|
+
klass.sorted_commands.each do |cmd|
|
55
|
+
rel_path = Magellan::Cli::Command::RESOURCES.values.include?(cmd.name) ? "./#{cmd.name}.html" : "##{cmd.name}"
|
56
|
+
f.puts "- [%s](%s)" % [Thor.send(:banner, cmd, false, false), rel_path]
|
57
|
+
end
|
58
|
+
f.puts
|
59
|
+
|
60
|
+
f.puts "## Global Options"
|
61
|
+
f.puts
|
62
|
+
change_global_var_temporarily(["$stdout", f], ["$stderr", f]) do
|
63
|
+
f.puts "```text"
|
64
|
+
klass.send(:print_options, @shell, klass.class_options.values)
|
65
|
+
f.puts "```"
|
66
|
+
f.puts
|
67
|
+
end
|
68
|
+
f.puts
|
69
|
+
|
70
|
+
f.puts "## Details"
|
71
|
+
klass.sorted_commands.each do |cmd|
|
72
|
+
next if Magellan::Cli::Command::RESOURCES.values.include?(cmd.name)
|
73
|
+
f.puts "### <a name=\"#{cmd.name}\"></a>#{cmd.name}"
|
74
|
+
f.puts
|
75
|
+
f.puts "```text"
|
76
|
+
f.puts Thor.send(:banner, cmd)
|
77
|
+
f.puts "```"
|
78
|
+
f.puts
|
79
|
+
unless cmd.options.empty?
|
80
|
+
change_global_var_temporarily(["$stdout", f], ["$stderr", f]) do
|
81
|
+
f.puts "```text"
|
82
|
+
klass.send(:print_options, @shell, cmd.options.values)
|
83
|
+
f.puts "```"
|
84
|
+
f.puts
|
85
|
+
end
|
86
|
+
end
|
87
|
+
if cmd.long_description
|
88
|
+
f.puts cmd.long_description
|
89
|
+
else
|
90
|
+
f.puts cmd.description
|
91
|
+
end
|
92
|
+
f.puts
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -64,7 +64,7 @@ module Magellan
|
|
64
64
|
i = fields.index(f)
|
65
65
|
next unless i
|
66
66
|
fields[i] = obj[:name]
|
67
|
-
res = obj[:resource] || ((k = Resources.const_get(obj[:class])) ? k.
|
67
|
+
res = obj[:resource] || ((k = Resources.const_get(obj[:class])) ? k.resource_key : nil)
|
68
68
|
res2 = get_json("/admin/#{res}.json", {"compact" => true})
|
69
69
|
associations[f] = res2.each_with_object({}){|r,d| d[ r["id"].to_i ] = r["label"] }
|
70
70
|
end
|
@@ -81,7 +81,7 @@ module Magellan
|
|
81
81
|
|
82
82
|
|
83
83
|
def query_list
|
84
|
-
get_json("/admin/#{self.class.
|
84
|
+
get_json("/admin/#{self.class.resource_key}.json", default_query)
|
85
85
|
end
|
86
86
|
private :query_list
|
87
87
|
|
@@ -115,7 +115,7 @@ module Magellan
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def show(id)
|
118
|
-
r = get_json("/admin/#{self.class.
|
118
|
+
r = get_json("/admin/#{self.class.resource_key}/#{id}.json")
|
119
119
|
t = Text::Table.new
|
120
120
|
t.head = ["field", "value"]
|
121
121
|
|
@@ -151,7 +151,7 @@ module Magellan
|
|
151
151
|
|
152
152
|
def select(name)
|
153
153
|
q = build_query("name" => name).update(default_query)
|
154
|
-
update_first_result(self.class.parameter_name, "/admin/#{self.class.
|
154
|
+
update_first_result(self.class.parameter_name, "/admin/#{self.class.resource_key}.json", q)
|
155
155
|
end
|
156
156
|
|
157
157
|
def deselect
|
@@ -162,38 +162,45 @@ module Magellan
|
|
162
162
|
|
163
163
|
def self.inherited(klass)
|
164
164
|
base_name = klass.name.split(/::/).last
|
165
|
-
res_name = base_name
|
165
|
+
res_name = Magellan::Cli::Command::RESOURCES[base_name] or raise "resource not found for #{base_name}"
|
166
|
+
|
167
|
+
klass.instance_eval(<<-EOM, __FILE__, __LINE__ + 1)
|
168
|
+
def resource_name
|
169
|
+
"#{res_name}"
|
170
|
+
end
|
171
|
+
EOM
|
172
|
+
|
166
173
|
klass.module_eval(<<-EOM, __FILE__, __LINE__ + 1)
|
167
174
|
no_commands do
|
168
|
-
cattr_accessor :
|
175
|
+
cattr_accessor :resource_key
|
169
176
|
cattr_accessor :resource_dependency
|
170
177
|
cattr_accessor :field_associations
|
171
178
|
cattr_accessor :hidden_fields, :multiline_fields
|
172
179
|
|
173
180
|
def self.parameter_name
|
174
|
-
|
181
|
+
resource_key.gsub(/~/, "_")
|
175
182
|
end
|
176
183
|
def parameter_name
|
177
184
|
self.class.parameter_name
|
178
185
|
end
|
179
186
|
end
|
180
187
|
|
181
|
-
desc "list", "list #{
|
188
|
+
desc "list", "Show a list of the #{res_name.pluralize}"
|
182
189
|
def list
|
183
190
|
super
|
184
191
|
end
|
185
192
|
|
186
|
-
desc "show ID", "
|
193
|
+
desc "show ID", "Show the detail of the #{res_name} specified by ID"
|
187
194
|
def show(id)
|
188
195
|
super(id)
|
189
196
|
end
|
190
197
|
|
191
|
-
desc "select NAME", "
|
198
|
+
desc "select NAME", "Select the #{res_name} by NAME"
|
192
199
|
def select(name)
|
193
200
|
super
|
194
201
|
end
|
195
202
|
|
196
|
-
desc "deselect", "
|
203
|
+
desc "deselect", "Deselect the #{res_name}"
|
197
204
|
def deselect
|
198
205
|
super
|
199
206
|
end
|
@@ -6,7 +6,7 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class ClientVersion < Base
|
9
|
-
self.
|
9
|
+
self.resource_key = "client_version"
|
10
10
|
self.resource_dependency = {"project" => "project"}
|
11
11
|
|
12
12
|
self.hidden_fields = %w[project_id created_at updated_at].map(&:freeze).freeze
|
@@ -14,7 +14,7 @@ module Magellan
|
|
14
14
|
"stage_title_id" => {name: "stage", class: "Stage"},
|
15
15
|
}
|
16
16
|
|
17
|
-
desc "create VERSION", "
|
17
|
+
desc "create VERSION", "Create a new #{resource_name}"
|
18
18
|
def create(version)
|
19
19
|
stage = load_selection("stage")
|
20
20
|
params = {
|
@@ -23,7 +23,7 @@ module Magellan
|
|
23
23
|
"version" => version,
|
24
24
|
}
|
25
25
|
}
|
26
|
-
post_json("/admin/#{
|
26
|
+
post_json("/admin/#{resource_key}/new.json", params)
|
27
27
|
# TODO implement select method
|
28
28
|
# select(version)
|
29
29
|
end
|
@@ -6,11 +6,11 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class Cloudsql < Base
|
9
|
-
self.
|
9
|
+
self.resource_key = "cloudsql~database"
|
10
10
|
self.resource_dependency = {"stage" => "stage"}
|
11
11
|
self.hidden_fields = %w[cloudsql_instance_id].map(&:freeze).freeze
|
12
12
|
|
13
|
-
desc "create NAME", "
|
13
|
+
desc "create NAME", "Create a new #{resource_name} database with NAME"
|
14
14
|
def create(name)
|
15
15
|
o = load_selection("stage")
|
16
16
|
params = {
|
@@ -19,13 +19,13 @@ module Magellan
|
|
19
19
|
"name" => name,
|
20
20
|
}
|
21
21
|
}
|
22
|
-
post_json("/admin/#{
|
22
|
+
post_json("/admin/#{resource_key}/new.json", params)
|
23
23
|
select(name)
|
24
24
|
end
|
25
25
|
|
26
|
-
desc "delete ID", "
|
26
|
+
desc "delete ID", "Delete the #{resource_name} database specified by ID"
|
27
27
|
def delete(id)
|
28
|
-
super("/admin/#{
|
28
|
+
super("/admin/#{resource_key}/#{id}/delete.js")
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -6,7 +6,7 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class Container < Base
|
9
|
-
self.
|
9
|
+
self.resource_key = "container~instance"
|
10
10
|
self.resource_dependency = {"stage" => "stage-version"}
|
11
11
|
self.hidden_fields = %w[created_at updated_at].map(&:freeze).freeze
|
12
12
|
self.multiline_fields = %w[docker_properties_json links_yaml publishings_yaml volumes_yaml env_yaml].map(&:freeze).freeze
|
@@ -6,7 +6,7 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class Image < Base
|
9
|
-
self.
|
9
|
+
self.resource_key = "container~image"
|
10
10
|
self.resource_dependency = {"stage" => "stage-version"}
|
11
11
|
self.hidden_fields = %w[function_id function_type created_at updated_at].map(&:freeze).freeze
|
12
12
|
self.field_associations = {"stage_version_id" => {name: "stage", resource: "stage~version"} }
|
@@ -6,17 +6,18 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class Organization < Base
|
9
|
-
|
9
|
+
|
10
|
+
self.resource_key = "magellan~auth~organization"
|
10
11
|
# self.field_associations = {"creator_id" => {name: "creator", class: "User"} }
|
11
12
|
|
12
|
-
desc "create NAME", "create
|
13
|
+
desc "create NAME", "create a new #{resource_name} with NAME"
|
13
14
|
def create(name)
|
14
15
|
params = {
|
15
16
|
parameter_name => {
|
16
17
|
"name" => name,
|
17
18
|
}
|
18
19
|
}
|
19
|
-
post_json("/admin/#{self.
|
20
|
+
post_json("/admin/#{self.resource_key}/new.json", params)
|
20
21
|
select(name)
|
21
22
|
end
|
22
23
|
end
|
@@ -6,19 +6,19 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class Project < Base
|
9
|
-
self.
|
9
|
+
self.resource_key = "project"
|
10
10
|
self.resource_dependency = nil
|
11
11
|
self.hidden_fields = %w[default_nebula_id created_at updated_at].map(&:freeze).freeze
|
12
12
|
self.field_associations = {"organization_id" => {name: "organization", class: "Organization"} }
|
13
13
|
|
14
|
-
desc "update ATTRIBUTES", "
|
14
|
+
desc "update ATTRIBUTES", "Update the ATTRIBUTES of the selected #{resource_name}"
|
15
15
|
def update(attrs)
|
16
16
|
s = load_selection("project")
|
17
17
|
attrs = JSON.parse(File.readable?(attrs) ? File.read(attrs) : attrs)
|
18
18
|
put_json("/admin/project/#{s['id']}/edit", {"project" => attrs})
|
19
19
|
end
|
20
20
|
|
21
|
-
desc "create NAME", "
|
21
|
+
desc "create NAME", "Create a new #{resource_name} with NAME"
|
22
22
|
def create(name)
|
23
23
|
o = load_selection(Organization.parameter_name)
|
24
24
|
params = {
|
@@ -27,7 +27,7 @@ module Magellan
|
|
27
27
|
"name" => name,
|
28
28
|
}
|
29
29
|
}
|
30
|
-
post_json("/admin/#{
|
30
|
+
post_json("/admin/#{resource_key}/new.json", params)
|
31
31
|
select(name)
|
32
32
|
end
|
33
33
|
end
|
@@ -7,12 +7,12 @@ module Magellan
|
|
7
7
|
module Resources
|
8
8
|
|
9
9
|
class Stage < Base
|
10
|
-
self.
|
10
|
+
self.resource_key = "stage~title"
|
11
11
|
self.resource_dependency = {"project" => "project"}
|
12
12
|
self.hidden_fields = %w[nebula_id created_at updated_at].map(&:freeze).freeze
|
13
13
|
self.field_associations = {"project_id" => {name: "project", class: "Project"} }
|
14
14
|
|
15
|
-
desc "create NAME [-t development|staging|production|other]", "
|
15
|
+
desc "create NAME [-t development|staging|production|other]", "Create a new #{resource_name} with Name and Type"
|
16
16
|
option :t, type: :string, default: "development", desc: "-t development|staging|production. specify Stage Type"
|
17
17
|
def create(name)
|
18
18
|
type = options["t"]
|
@@ -27,11 +27,11 @@ module Magellan
|
|
27
27
|
"stage_type" => type,
|
28
28
|
}
|
29
29
|
}
|
30
|
-
post_json("/admin/#{
|
30
|
+
post_json("/admin/#{resource_key}/new.json", params)
|
31
31
|
select(name)
|
32
32
|
end
|
33
33
|
|
34
|
-
desc "select NAME", "
|
34
|
+
desc "select NAME", "Select the #{resource_name} named by NAME"
|
35
35
|
def select(name)
|
36
36
|
q = build_query("name" => name).update(default_query)
|
37
37
|
r = update_first_result("stage", "/admin/stage~title.json", q)
|
@@ -45,7 +45,7 @@ module Magellan
|
|
45
45
|
update_first_result("stage-version", "/admin/stage~version.json", q, %w[id])
|
46
46
|
end
|
47
47
|
|
48
|
-
desc "deselect", "
|
48
|
+
desc "deselect", "Deselect the #{resource_name}"
|
49
49
|
def deselect
|
50
50
|
update_selections do |s|
|
51
51
|
s.delete("stage")
|
@@ -53,12 +53,12 @@ module Magellan
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
desc "planning", "
|
56
|
+
desc "planning", "Switch to planning to build next released version"
|
57
57
|
def planning
|
58
58
|
switch_version(1)
|
59
59
|
end
|
60
60
|
|
61
|
-
desc "current", "
|
61
|
+
desc "current", "Switch to current released version"
|
62
62
|
def current
|
63
63
|
switch_version(2)
|
64
64
|
end
|
@@ -71,7 +71,7 @@ module Magellan
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
desc "prepare", "
|
74
|
+
desc "prepare", "Prepare the #{Container.resource_name.pluralize}"
|
75
75
|
def prepare
|
76
76
|
s = load_selection("stage")
|
77
77
|
id = s["id"]
|
@@ -79,7 +79,7 @@ module Magellan
|
|
79
79
|
Container.new.show_list(r["result"])
|
80
80
|
end
|
81
81
|
|
82
|
-
desc "repair", "
|
82
|
+
desc "repair", "Repair the #{resource_name} status"
|
83
83
|
def repair
|
84
84
|
r = call_repair
|
85
85
|
puts r["success"] ? "\e[32msucceeded to repair stage\e[0m" : "\e[31mfailed to repair stage\e[0m"
|
@@ -93,14 +93,14 @@ module Magellan
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
desc "update ATTRIBUTES", "
|
96
|
+
desc "update ATTRIBUTES", "Update ATTRIBUTES of the #{resource_name}"
|
97
97
|
def update(attrs)
|
98
98
|
s = load_selection("stage")
|
99
99
|
attrs = JSON.parse(File.readable?(attrs) ? File.read(attrs) : attrs)
|
100
100
|
put_json("/admin/stage~title/#{s['id']}/edit", {"stage_title" => attrs})
|
101
101
|
end
|
102
102
|
|
103
|
-
desc "release_now", "
|
103
|
+
desc "release_now", "Release the changes now"
|
104
104
|
option :A, type: :boolean, default: false, desc: "-A async mode. release_now returns soon"
|
105
105
|
option :i, type: :numeric, default: 10, desc: "-i polling interval(seconds)"
|
106
106
|
option :t, type: :numeric, default: 600, desc: "-t timeout(seconds)"
|
@@ -156,7 +156,7 @@ module Magellan
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
-
desc "logs", "
|
159
|
+
desc "logs", "Fetch the logs of the #{Worker.resource_name.pluralize}"
|
160
160
|
def logs
|
161
161
|
s = load_selection("stage")
|
162
162
|
id = s["id"]
|
@@ -168,7 +168,7 @@ module Magellan
|
|
168
168
|
end
|
169
169
|
end
|
170
170
|
|
171
|
-
desc "set_container_num NUM", "
|
171
|
+
desc "set_container_num NUM", "Set the number of #{Container.resource_name.pluralize} for the selected #{Image.resource_name}"
|
172
172
|
def set_container_num(num)
|
173
173
|
s = load_selection("stage")
|
174
174
|
v = load_selection("stage-version")
|
@@ -176,7 +176,7 @@ module Magellan
|
|
176
176
|
post_json("/admin/stage~version/#{v["id"]}/set_container_num.json", { container_num: num, container_image_id: i["id"] })
|
177
177
|
end
|
178
178
|
|
179
|
-
desc "reload", "
|
179
|
+
desc "reload", "Reload the last selections"
|
180
180
|
def reload
|
181
181
|
s = load_selection("stage")
|
182
182
|
select(s["name"])
|
@@ -6,11 +6,11 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class Team < Base
|
9
|
-
self.
|
9
|
+
self.resource_key = "magellan~auth~team"
|
10
10
|
self.resource_dependency = { "organization" => Organization.parameter_name }
|
11
11
|
self.field_associations = {"organization_id" => {name: "organization", class: "Organization"} }
|
12
12
|
|
13
|
-
desc "create NAME ROLE", "
|
13
|
+
desc "create NAME ROLE", "Create a new #{resource_name} with NAME and ROLE"
|
14
14
|
def create(name, role)
|
15
15
|
unless %w{ reader admin }.include?(role)
|
16
16
|
raise "ROLE should be 'reader' or 'admin'"
|
@@ -23,18 +23,18 @@ module Magellan
|
|
23
23
|
"role" => role,
|
24
24
|
}
|
25
25
|
}
|
26
|
-
post_json("/admin/#{self.
|
26
|
+
post_json("/admin/#{self.resource_key}/new.json", params)
|
27
27
|
select(name)
|
28
28
|
end
|
29
29
|
|
30
30
|
=begin
|
31
|
-
desc "invite EMAIL", "
|
31
|
+
desc "invite EMAIL", "Invite a user to the #{Team.resource_name}"
|
32
32
|
def invite(email)
|
33
33
|
o = load_selection(parameter_name)
|
34
34
|
params = {
|
35
35
|
"email" => email
|
36
36
|
}
|
37
|
-
post_json("/admin/#{self.
|
37
|
+
post_json("/admin/#{self.resource_key}/#{o["id"]}/team_invite.json", params)
|
38
38
|
end
|
39
39
|
=end
|
40
40
|
end
|
@@ -6,10 +6,10 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class TransactionRouter < Base
|
9
|
-
self.
|
9
|
+
self.resource_key = "functions~transaction_router"
|
10
10
|
self.resource_dependency = {"stage" => Stage.parameter_name}
|
11
11
|
|
12
|
-
desc "create NAME", "
|
12
|
+
desc "create NAME", "Create a new #{resource_name} with NAME"
|
13
13
|
def create(name)
|
14
14
|
s = load_selection("stage-version")
|
15
15
|
params = {
|
@@ -19,7 +19,7 @@ module Magellan
|
|
19
19
|
# "instance_base_name" => name,
|
20
20
|
}
|
21
21
|
}
|
22
|
-
post_json("/admin/#{self.
|
22
|
+
post_json("/admin/#{self.resource_key}/new.json", params)
|
23
23
|
select(name)
|
24
24
|
end
|
25
25
|
|
@@ -6,13 +6,13 @@ module Magellan
|
|
6
6
|
module Resources
|
7
7
|
|
8
8
|
class Worker < Base
|
9
|
-
self.
|
9
|
+
self.resource_key = "functions~worker"
|
10
10
|
self.resource_dependency = {"stage" => "stage-version"}
|
11
11
|
self.hidden_fields = %w[created_at updated_at].map(&:freeze).freeze
|
12
12
|
self.multiline_fields = %w[migration_command_1 migration_command_2 run_command environment_vars_yaml].map(&:freeze).freeze
|
13
13
|
self.field_associations = {"stage_version_id" => {name: "stage", resource: "stage~version"} }
|
14
14
|
|
15
|
-
desc "create NAME, IMAGE", "
|
15
|
+
desc "create NAME, IMAGE", "Create a new #{resource_name} with NAME and IMAGE"
|
16
16
|
method_option :attributes_yaml, aliases: "-A", desc: "path to YAML file which defines attributes"
|
17
17
|
def create(name, image_name)
|
18
18
|
s = load_selection("stage-version")
|
@@ -30,11 +30,11 @@ module Magellan
|
|
30
30
|
# "instance_base_name" => name,
|
31
31
|
}.update(attrs)
|
32
32
|
}
|
33
|
-
post_json("/admin/#{self.
|
33
|
+
post_json("/admin/#{self.resource_key}/new.json", params)
|
34
34
|
select(name)
|
35
35
|
end
|
36
36
|
|
37
|
-
desc "update
|
37
|
+
desc "update ATTRIBUTES", "Update the ATTRIBUTES(filename or JSON) of the selected #{resource_name}"
|
38
38
|
def update(attrs)
|
39
39
|
if File.readable?(attrs)
|
40
40
|
attrs = YAML.load_file(attrs)
|
@@ -47,10 +47,10 @@ module Magellan
|
|
47
47
|
params = {
|
48
48
|
parameter_name => attrs
|
49
49
|
}
|
50
|
-
put_json("/admin/#{
|
50
|
+
put_json("/admin/#{resource_key}/#{w["id"]}/edit.js", params)
|
51
51
|
end
|
52
52
|
|
53
|
-
desc "prepare_images", "prepare
|
53
|
+
desc "prepare_images", "prepare the #{Image.resource_name.pluralize} for the selected #{Worker.resource_name}"
|
54
54
|
def prepare_images
|
55
55
|
s = load_selection("functions_worker")
|
56
56
|
id = s["id"]
|
data/lib/magellan/cli/version.rb
CHANGED
data/lib/magellan/cli.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Magellan::Cli::Command do
|
5
|
+
let(:command){ Magellan::Cli::Command.new }
|
6
|
+
let(:string){ "string" }
|
7
|
+
|
8
|
+
describe :login do
|
9
|
+
describe :intaractive do
|
10
|
+
before do
|
11
|
+
$stdout = StringIO.new
|
12
|
+
allow(Magellan::Cli::Http).to receive_message_chain(:new, :login!).and_return("OK")
|
13
|
+
end
|
14
|
+
it "nothing options" do
|
15
|
+
allow($stdin).to receive(:gets).and_return(string).once
|
16
|
+
allow($stdin).to receive(:noecho).and_return(string).once
|
17
|
+
expect(command.login).to eq "OK"
|
18
|
+
expect($stdout.string).to eq "email: password: \n"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "only email" do
|
22
|
+
allow($stdin).to receive(:noecho).and_return(string).twice
|
23
|
+
expect(command.invoke(:login, [], {email: string})).to eq "OK"
|
24
|
+
expect($stdout.string).to eq "password: \n"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "only password" do
|
28
|
+
allow($stdin).to receive(:gets).and_return(string).once
|
29
|
+
expect(command.invoke(:login, [], {password: string})).to eq "OK"
|
30
|
+
expect($stdout.string).to eq "email: "
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magellan-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- akm2000
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- lib/magellan/cli/file_access.rb
|
149
149
|
- lib/magellan/cli/http.rb
|
150
150
|
- lib/magellan/cli/login.rb
|
151
|
+
- lib/magellan/cli/reference_generator.rb
|
151
152
|
- lib/magellan/cli/resources.rb
|
152
153
|
- lib/magellan/cli/resources/base.rb
|
153
154
|
- lib/magellan/cli/resources/client_version.rb
|
@@ -165,6 +166,7 @@ files:
|
|
165
166
|
- lib/magellan/cli/version.rb
|
166
167
|
- magellan-cli.gemspec
|
167
168
|
- spec/magellan/cli/Magellan.yml
|
169
|
+
- spec/magellan/cli/command_spec.rb
|
168
170
|
- spec/magellan/cli/login_page.html
|
169
171
|
- spec/magellan/cli/login_spec.rb
|
170
172
|
- spec/magellan/cli/resources/client_version_spec.rb
|
@@ -199,6 +201,7 @@ specification_version: 4
|
|
199
201
|
summary: commandline tools for magellanic cloud service.
|
200
202
|
test_files:
|
201
203
|
- spec/magellan/cli/Magellan.yml
|
204
|
+
- spec/magellan/cli/command_spec.rb
|
202
205
|
- spec/magellan/cli/login_page.html
|
203
206
|
- spec/magellan/cli/login_spec.rb
|
204
207
|
- spec/magellan/cli/resources/client_version_spec.rb
|