magellan-cli 0.2.18 → 0.2.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb40bd948d572f7f0a642dc9b3baff058c112eb4
4
- data.tar.gz: 50c8e29d10da813eddf77cf192ab9bb7e3782bf3
3
+ metadata.gz: 727be865a8fa69b098afe51d712bad1a31a45724
4
+ data.tar.gz: 506f81d124f8eb15b767f11f69feaf19d1684257
5
5
  SHA512:
6
- metadata.gz: e9d3a89a666fe6454a1c1bd1f1ccb65b7a6daa9f334ab253d86f65cae27a5aff4e35586e9a78abed6b7d457c794a5abe06cc5b51552143f02f9047fd0a22f7c2
7
- data.tar.gz: d3db854dcefaa6d1a7b6bbc62b5566a355a473496331166e5ad1c49ae85ed0689672d07c707e40e1d1819cd117af02df8968c760e8a686f954901f62bca5e08e
6
+ metadata.gz: dbecdde19ac927dcc2259a967a944e697aca441a12ec3f518d25a9a31d133663ed90e8a94daf719407f059d7933a1baa07248e8e0fe961640a8feb71eae47ab4
7
+ data.tar.gz: 935c8e96e86ec2cf3caf5742b40495bf941ebc3761c2464b72e93517d2709dc2a3fa4675bf27b8e02ef0d31bd34a1dce9e6362f9337c657d55400f7dbe72257c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- magellan-cli (0.2.18)
4
+ magellan-cli (0.2.19)
5
5
  activesupport (~> 4.1.4)
6
6
  groovenauts-thor
7
7
  httpclient (~> 2.5)
@@ -32,37 +32,23 @@ module Magellan
32
32
 
33
33
  shell.say
34
34
  shell.say "RESOURCES:"
35
- shell.say " " << RESOURCES.keys.join(", ")
35
+ shell.say " " << Resources::MAPPING.keys.join(", ")
36
36
  shell.say " type `#{File.basename($0)} help RESOURCE` for more detail"
37
37
  shell.say
38
38
  end
39
39
  end
40
40
 
41
- RESOURCES =\
42
- {
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}"
41
+ Resources::MAPPING.each do |classname, name|
42
+ desc "#{name} SUBCOMMAND ...ARGS", "Manage #{name.pluralize}"
57
43
  subcommand name, ::Magellan::Cli::Resources.const_get(classname)
58
44
  end
59
45
 
60
- COMMAND_ORDER = %w[login] + RESOURCES.values
46
+ COMMAND_ORDER = %w[login] + Resources::MAPPING.values
61
47
 
62
- #desc "direct SUBCOMMAND ...ARGS", "send request directly"
48
+ #desc "direct SUBCOMMAND ...ARGS", "Send request directly"
63
49
  #subcommand "direct", ::Magellan::Cli::Direct
64
50
 
65
- desc "login", "login to the Magellan server"
51
+ desc "login", "Login to the Magellan server"
66
52
  method_option :email, aliases: "-e", desc: "email address for login"
67
53
  method_option :password, aliases: "-p", desc: "password for login"
68
54
  def login
@@ -5,23 +5,23 @@ module Magellan
5
5
  module Cli
6
6
  class Direct < ::Magellan::Cli::Http
7
7
 
8
- desc "get PATH", "send GET request with PATH"
8
+ desc "get PATH", "Send GET request with PATH"
9
9
  def get(path)
10
10
  r = get_json(path)
11
11
  $stdout.puts(JSON.pretty_generate(r))
12
12
  end
13
13
 
14
- desc "post PATH [PARAMS]", "send POST request with PATH and PARAMS"
14
+ desc "post PATH [PARAMS]", "Send POST request with PATH and PARAMS"
15
15
  def post(path, params = nil)
16
16
  post_json(path)
17
17
  end
18
18
 
19
- desc "put PATH [PARAMS]", "send PUT request with PATH and PARAMS"
19
+ desc "put PATH [PARAMS]", "Send PUT request with PATH and PARAMS"
20
20
  def put(path, params = nil)
21
21
  put_json(path)
22
22
  end
23
23
 
24
- desc "delete PATH", "send DELETE request with PATH"
24
+ desc "delete PATH", "Send DELETE request with PATH"
25
25
  def delete(path)
26
26
  delete(path)
27
27
  end
@@ -7,8 +7,16 @@ module Magellan
7
7
  class NotSelected < StandardError
8
8
  end
9
9
 
10
+ SELECTION_FILENAME = ".magellan-cli"
11
+
12
+ module_function
13
+
14
+ def remove_selection_file
15
+ File.exist?(SELECTION_FILENAME) && File.delete(SELECTION_FILENAME)
16
+ end
17
+
10
18
  def load_selections
11
- File.readable?(".magellan-cli") ? YAML.load_file(".magellan-cli") : {}
19
+ File.readable?(SELECTION_FILENAME) ? YAML.load_file(SELECTION_FILENAME) : {}
12
20
  end
13
21
 
14
22
  def load_selection(name)
@@ -7,8 +7,11 @@ module Magellan
7
7
 
8
8
  no_commands do
9
9
 
10
+ def cli
11
+ @cli ||= Cli::Login.new
12
+ end
13
+
10
14
  def login!(email, password)
11
- cli = Cli::Login.new
12
15
  logined = cli.api_login!(email, password)
13
16
  if logined
14
17
  success("OK")
@@ -18,7 +21,6 @@ module Magellan
18
21
  end
19
22
 
20
23
  def access_api
21
- cli = Cli::Login.new
22
24
  if block_given?
23
25
  auth = cli.login_auth
24
26
  if auth.nil? || auth.empty?
@@ -55,6 +57,7 @@ module Magellan
55
57
  def get_json(rel_path, params = {})
56
58
  access_api do |api|
57
59
  url = "#{api.base_url}#{rel_path}"
60
+ params.update(yield) if block_given?
58
61
  params = api.login_auth.merge(params)
59
62
  if params && !params.empty?
60
63
  url << '?' << params.map{|k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
@@ -16,7 +16,7 @@ module Magellan
16
16
  @shell = Thor::Shell::Basic.new
17
17
  change_global_var_temporarily(["$PROGRAM_NAME", "magellan-cli"]) do
18
18
  process(Magellan::Cli::Command, "index.md")
19
- Magellan::Cli::Command::RESOURCES.each do |class_name, res_name|
19
+ Magellan::Cli::Resources::MAPPING.each do |class_name, res_name|
20
20
  klass = Magellan::Cli::Resources.const_get(class_name)
21
21
  process(klass, "#{res_name}.md", res_name)
22
22
  end
@@ -52,7 +52,7 @@ module Magellan
52
52
  f.puts "## Commands"
53
53
  f.puts
54
54
  klass.sorted_commands.each do |cmd|
55
- rel_path = Magellan::Cli::Command::RESOURCES.values.include?(cmd.name) ? "./#{cmd.name}.html" : "##{cmd.name}"
55
+ rel_path = Magellan::Cli::Resources::MAPPING.values.include?(cmd.name) ? "./#{cmd.name}.html" : "##{cmd.name}"
56
56
  f.puts "- [%s](%s)" % [Thor.send(:banner, cmd, false, false), rel_path]
57
57
  end
58
58
  f.puts
@@ -69,7 +69,7 @@ module Magellan
69
69
 
70
70
  f.puts "## Details"
71
71
  klass.sorted_commands.each do |cmd|
72
- next if Magellan::Cli::Command::RESOURCES.values.include?(cmd.name)
72
+ next if Magellan::Cli::Resources::MAPPING.values.include?(cmd.name)
73
73
  f.puts "### <a name=\"#{cmd.name}\"></a>#{cmd.name}"
74
74
  f.puts
75
75
  f.puts "```text"
@@ -22,6 +22,13 @@ module Magellan
22
22
 
23
23
  no_commands do
24
24
 
25
+ def load_selection!(name, &block)
26
+ return access_api{ load_selection(name, &block) }
27
+ end
28
+ def update_selections!(hash = nil, &block)
29
+ return access_api{ update_selections(hash, &block) }
30
+ end
31
+
25
32
  def build_query(hash)
26
33
  @@no ||= 0
27
34
  r = {}
@@ -34,15 +41,16 @@ module Magellan
34
41
  end
35
42
 
36
43
  def default_query
37
- sel = load_selections
38
- q = {}
39
- (self.class.resource_dependency || {}).each do |f, res|
40
- r = sel[res]
41
- raise NotSelected, "No #{f} selected" unless r
42
- q[f] = r["id"]
44
+ access_api do |cli|
45
+ sel = load_selections
46
+ q = {}
47
+ (self.class.resource_dependency || {}).each do |f, res|
48
+ r = sel[res]
49
+ raise NotSelected, "No #{f} selected" unless r
50
+ q[f] = r["id"]
51
+ end
52
+ build_query(q)
43
53
  end
44
- return build_query(q)
45
-
46
54
  end
47
55
 
48
56
  DEFAULT_SELECTION_FIELDS = %w[id name].freeze
@@ -54,7 +62,7 @@ module Magellan
54
62
  obj = fields.each_with_object({}) do |f, d|
55
63
  d[f] = r[f]
56
64
  end
57
- update_selections(name => obj)
65
+ update_selections!(name => obj)
58
66
  return r
59
67
  end
60
68
 
@@ -81,7 +89,7 @@ module Magellan
81
89
 
82
90
 
83
91
  def query_list
84
- get_json("/admin/#{self.class.resource_key}.json", default_query)
92
+ get_json("/admin/#{self.class.resource_key}.json"){ default_query }
85
93
  end
86
94
  private :query_list
87
95
 
@@ -155,14 +163,14 @@ module Magellan
155
163
  end
156
164
 
157
165
  def deselect
158
- update_selections do |s|
166
+ update_selections! do |s|
159
167
  s.delete(self.class.parameter_name)
160
168
  end
161
169
  end
162
170
 
163
171
  def self.inherited(klass)
164
172
  base_name = klass.name.split(/::/).last
165
- res_name = Magellan::Cli::Command::RESOURCES[base_name] or raise "resource not found for #{base_name}"
173
+ res_name = Magellan::Cli::Resources::MAPPING[base_name] or raise "resource not found for #{base_name}"
166
174
 
167
175
  klass.instance_eval(<<-EOM, __FILE__, __LINE__ + 1)
168
176
  def resource_name
@@ -16,7 +16,7 @@ module Magellan
16
16
 
17
17
  desc "create VERSION", "Create a new #{resource_name}"
18
18
  def create(version)
19
- stage = load_selection("stage")
19
+ stage = load_selection!("stage")
20
20
  params = {
21
21
  parameter_name => {
22
22
  "stage_title_id" => stage["id"],
@@ -12,7 +12,7 @@ module Magellan
12
12
 
13
13
  desc "create NAME", "Create a new #{resource_name} database with NAME"
14
14
  def create(name)
15
- o = load_selection("stage")
15
+ o = load_selection!("stage")
16
16
  params = {
17
17
  parameter_name => {
18
18
  "stage_title_id" => o["id"],
@@ -10,7 +10,7 @@ module Magellan
10
10
  self.resource_key = "magellan~auth~organization"
11
11
  # self.field_associations = {"creator_id" => {name: "creator", class: "User"} }
12
12
 
13
- desc "create NAME", "create a new #{resource_name} with NAME"
13
+ desc "create NAME", "Create a new #{resource_name} with NAME"
14
14
  def create(name)
15
15
  params = {
16
16
  parameter_name => {
@@ -13,14 +13,14 @@ module Magellan
13
13
 
14
14
  desc "update ATTRIBUTES", "Update the ATTRIBUTES of the selected #{resource_name}"
15
15
  def update(attrs)
16
- s = load_selection("project")
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
21
  desc "create NAME", "Create a new #{resource_name} with NAME"
22
22
  def create(name)
23
- o = load_selection(Organization.parameter_name)
23
+ o = load_selection!(Organization.parameter_name)
24
24
  params = {
25
25
  parameter_name => {
26
26
  "organization_id" => o["id"],
@@ -19,7 +19,7 @@ module Magellan
19
19
  unless %w{ development staging production other }.include?(type)
20
20
  raise "Unknown Stage Type #{type}"
21
21
  end
22
- proj = load_selection("project")
22
+ proj = load_selection!("project")
23
23
  params = {
24
24
  parameter_name => {
25
25
  "project_id" => proj["id"],
@@ -47,7 +47,7 @@ module Magellan
47
47
 
48
48
  desc "deselect", "Deselect the #{resource_name}"
49
49
  def deselect
50
- update_selections do |s|
50
+ update_selections! do |s|
51
51
  s.delete("stage")
52
52
  s.delete("stage-version")
53
53
  end
@@ -65,7 +65,7 @@ module Magellan
65
65
 
66
66
  no_commands do
67
67
  def switch_version(phase)
68
- s = load_selection("stage")
68
+ s = load_selection!("stage")
69
69
  q = build_query("title" => s["id"], "phase" => phase) # 1: workspace, 2: current, 3: used
70
70
  update_first_result("stage-version", "/admin/stage~version.json", q, %w[id])
71
71
  end
@@ -73,7 +73,7 @@ module Magellan
73
73
 
74
74
  desc "prepare", "Prepare the #{Container.resource_name.pluralize}"
75
75
  def prepare
76
- s = load_selection("stage")
76
+ s = load_selection!("stage")
77
77
  id = s["id"]
78
78
  r = post_json("/admin/stage~title/#{id}/simple_method_call.json", {method_name: "prepare_containers"})
79
79
  Container.new.show_list(r["result"])
@@ -87,7 +87,7 @@ module Magellan
87
87
 
88
88
  no_commands do
89
89
  def call_repair
90
- s = load_selection("stage")
90
+ s = load_selection!("stage")
91
91
  id = s["id"]
92
92
  post_json("/admin/stage~title/#{id}/simple_method_call.json", {method_name: "repair"})
93
93
  end
@@ -95,7 +95,7 @@ module Magellan
95
95
 
96
96
  desc "update ATTRIBUTES", "Update ATTRIBUTES of the #{resource_name}"
97
97
  def update(attrs)
98
- s = load_selection("stage")
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
@@ -106,14 +106,14 @@ module Magellan
106
106
  option :t, type: :numeric, default: 600, desc: "-t timeout(seconds)"
107
107
  def release_now
108
108
  spacer = "\r" << (" " * 20)
109
+ stage = load_selection!("stage")
109
110
  print "\rrelease starting"
110
- stage = load_selection("stage")
111
111
  id = stage["id"]
112
112
  res0 = post_json("/admin/stage~title/#{id}/simple_method_call.json", {method_name: "release_now"})
113
113
  res1 = res0["result"]
114
114
  if res1
115
115
  print spacer
116
- print "\rnow #{res1['status']}"
116
+ print "\r#{res1['status']}"
117
117
  else
118
118
  print spacer
119
119
  puts "\e[31m#{res0.inspect}\e[0m"
@@ -158,7 +158,7 @@ module Magellan
158
158
 
159
159
  desc "logs", "Fetch the logs of the #{Worker.resource_name.pluralize}"
160
160
  def logs
161
- s = load_selection("stage")
161
+ s = load_selection!("stage")
162
162
  id = s["id"]
163
163
  obj = get_json("/admin/stage~title/#{id}/logs.json")
164
164
  if obj["value"]
@@ -170,15 +170,15 @@ module Magellan
170
170
 
171
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
- s = load_selection("stage")
174
- v = load_selection("stage-version")
175
- i = load_selection("container_image")
173
+ s = load_selection!("stage")
174
+ v = load_selection!("stage-version")
175
+ i = load_selection!("container_image")
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
179
  desc "reload", "Reload the last selections"
180
180
  def reload
181
- s = load_selection("stage")
181
+ s = load_selection!("stage")
182
182
  select(s["name"])
183
183
  [Worker, Image, Container].each do |klass|
184
184
  s = (load_selections || {})[klass.parameter_name]
@@ -15,7 +15,7 @@ module Magellan
15
15
  unless %w{ reader admin }.include?(role)
16
16
  raise "ROLE should be 'reader' or 'admin'"
17
17
  end
18
- o = load_selection(Organization.parameter_name)
18
+ o = load_selection!(Organization.parameter_name)
19
19
  params = {
20
20
  parameter_name => {
21
21
  "organization_id" => o["id"],
@@ -30,7 +30,7 @@ module Magellan
30
30
  =begin
31
31
  desc "invite EMAIL", "Invite a user to the #{Team.resource_name}"
32
32
  def invite(email)
33
- o = load_selection(parameter_name)
33
+ o = load_selection!(parameter_name)
34
34
  params = {
35
35
  "email" => email
36
36
  }
@@ -11,7 +11,7 @@ module Magellan
11
11
 
12
12
  desc "create NAME", "Create a new #{resource_name} with NAME"
13
13
  def create(name)
14
- s = load_selection("stage-version")
14
+ s = load_selection!("stage-version")
15
15
  params = {
16
16
  self.class.parameter_name => {
17
17
  "stage_version_id" => s["id"],
@@ -15,7 +15,7 @@ module Magellan
15
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
- s = load_selection("stage-version")
18
+ s = load_selection!("stage-version")
19
19
  attrs =
20
20
  if path = options[:attributes_yaml]
21
21
  YAML.load_file(path)
@@ -41,7 +41,7 @@ module Magellan
41
41
  else
42
42
  attrs = JSON.parse(attrs)
43
43
  end
44
- w = load_selection(parameter_name)
44
+ w = load_selection!(parameter_name)
45
45
  self.class.hidden_fields.each do |f| attrs.delete(f) end
46
46
  self.class.field_associations.keys.each do |f| attrs.delete(f) end
47
47
  params = {
@@ -50,9 +50,9 @@ module Magellan
50
50
  put_json("/admin/#{resource_key}/#{w["id"]}/edit.js", params)
51
51
  end
52
52
 
53
- desc "prepare_images", "prepare the #{Image.resource_name.pluralize} for the selected #{Worker.resource_name}"
53
+ desc "prepare_images", "Prepare the #{Image.resource_name.pluralize} for the selected #{Worker.resource_name}"
54
54
  def prepare_images
55
- s = load_selection("functions_worker")
55
+ s = load_selection!("functions_worker")
56
56
  id = s["id"]
57
57
  r = post_json("/admin/functions~worker/#{id}/simple_method_call.json", {method_name: "prepare_images"})
58
58
  Image.new.show_list(r["result"])
@@ -23,6 +23,22 @@ module Magellan
23
23
  autoload :Container , "magellan/cli/resources/container"
24
24
 
25
25
  autoload :Cloudsql, "magellan/cli/resources/cloudsql"
26
+
27
+
28
+ MAPPING =\
29
+ {
30
+ "Organization" => "organization",
31
+ "Team" => "team",
32
+ "Project" => "project",
33
+ "Stage" => "stage",
34
+ "ClientVersion" => "client_version",
35
+ #"TransactionRouter" => "tr",
36
+ "Worker" => "worker",
37
+ "Image" => "image",
38
+ "Container" => "container",
39
+ "Cloudsql" => "cloudsql",
40
+ }
41
+
26
42
  end
27
43
  end
28
44
  end
@@ -1,5 +1,5 @@
1
1
  module Magellan
2
2
  module Cli
3
- VERSION = "0.2.18"
3
+ VERSION = "0.2.19"
4
4
  end
5
5
  end
@@ -77,4 +77,25 @@ describe Magellan::Cli::Login do
77
77
  end
78
78
  end
79
79
 
80
+ context :without_login do
81
+ before(:all){ Magellan::Cli::FileAccess.remove_selection_file }
82
+
83
+ Magellan::Cli::Resources::MAPPING.keys.each do |classname|
84
+ context classname do
85
+ klass = ::Magellan::Cli::Resources.const_get(classname)
86
+ let(:cmd){ klass.new }
87
+
88
+ klass.commands.each do |cmd_name, _|
89
+ next if cmd_name == "help"
90
+ m = klass.instance_method(cmd_name)
91
+ if m.arity == 0
92
+ it "raises Magellan::Cli::Error when #{cmd_name}" do
93
+ expect{ cmd.send(cmd_name) }.to raise_error(Magellan::Cli::Error, /not logined/i)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+
80
101
  end
@@ -5,9 +5,11 @@ describe Magellan::Cli::Resources::ClientVersion do
5
5
 
6
6
  let(:cmd){ Magellan::Cli::Resources::ClientVersion.new }
7
7
 
8
+ let(:cli){ double(:cli, login_auth: {"email" => "magellan@example.com", "toekn" => "dummy"}) }
9
+ before{ allow(cmd).to receive(:cli).and_return(cli) }
10
+
8
11
  describe :list do
9
12
  before do
10
- expect(cmd).to receive(:load_selections).and_return({"project" => {"id" => 1, "name" => "ProjectA"}})
11
13
  expect(cmd).to receive(:get_json).and_return([{id: 1, project_id: 1, stage_title_id: 1, version: "1.0.0", url_mapping_yaml: nil, status: "1" }])
12
14
  expect($stdout).to receive(:puts)
13
15
  end
@@ -5,6 +5,9 @@ describe Magellan::Cli::Resources::Organization do
5
5
 
6
6
  let(:cmd){ Magellan::Cli::Resources::Organization.new }
7
7
 
8
+ let(:cli){ double(:cli, login_auth: {"email" => "magellan@example.com", "toekn" => "dummy"}) }
9
+ before{ allow(cmd).to receive(:cli).and_return(cli) }
10
+
8
11
  describe :list do
9
12
  before do
10
13
  expect(cmd).to receive(:get_json).and_return([{id: 1, name: "org1", creator_id: 1}])
@@ -5,9 +5,11 @@ describe Magellan::Cli::Resources::Team do
5
5
 
6
6
  let(:cmd){ Magellan::Cli::Resources::Team.new }
7
7
 
8
+ let(:cli){ double(:cli, login_auth: {"email" => "magellan@example.com", "toekn" => "dummy"}) }
9
+ before{ allow(cmd).to receive(:cli).and_return(cli) }
10
+
8
11
  describe :list do
9
12
  before do
10
- expect(cmd).to receive(:load_selections).and_return({"magellan_auth_organization" => {"id" => "1", "name" => "testorg1"}})
11
13
  expect(cmd).to receive(:get_json).and_return([{id: 1, organization_id: 1, name: "team1" }])
12
14
  expect($stdout).to receive(:puts)
13
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magellan-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.18
4
+ version: 0.2.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - akm2000