magellan-cli 0.2.17 → 0.2.18
Sign up to get free protection for your applications and to get access to all the features.
- 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
|