magellan-cli 0.1.0 → 0.2.0

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: fe639545cc422de3632c16deacd1a9081fe0a37d
4
- data.tar.gz: 022da8e08cc29ac43e162c433439f378b5d3cee8
3
+ metadata.gz: b50c83378c4c2e7c8992abde1d7c6b6eb2b712c2
4
+ data.tar.gz: 3e193a9ab5f4f00afa3571ba160219574cb3d3bb
5
5
  SHA512:
6
- metadata.gz: 74b31f9bb8ae7f7ddee9c63090bc153178766ed0b31347b23c6c23ae5c37f6b05576137dd05fdf7eb28f6f91321432f0b58ced2c0f61f753d89b0be1e9d9da67
7
- data.tar.gz: 7a78d27190c4284673231bb57b049b9f598300232c03b1bcb2303697e1ba448f4e099e7fc5248581c30dd83d74250cc6b6d831cfc7247c850cd36a3dddb76770
6
+ metadata.gz: 140f87071bb2401945d826685ac7892a8da9c6ae8a1af162cea849e5e12e009d01b108d96dea472af50fe84bf556417c8cd6986fdec968733d2406690ca7eb17
7
+ data.tar.gz: 5cc732c2b875cc9d8425d6149824ff122cb3fff887009842b2c5940e29f51931fa69505303dddb3412ef6e2b28010086e4f1035e39ea5d86769b8bec870d2ce0
data/.gitignore CHANGED
@@ -13,3 +13,4 @@
13
13
  mkmf.log
14
14
  .magellan-cli
15
15
  worker.yml
16
+ worker2.yml
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- magellan-cli (0.1.0)
4
+ magellan-cli (0.2.0)
5
5
  activesupport (~> 4.1.4)
6
6
  httpclient
7
7
  nokogiri
data/lib/magellan/cli.rb CHANGED
@@ -15,6 +15,7 @@ module Magellan
15
15
  autoload :Error , "magellan/cli/errors"
16
16
  autoload :LoginError, "magellan/cli/errors"
17
17
 
18
+ autoload :FileAccess, "magellan/cli/file_access"
18
19
  JSON_HEADER = {
19
20
  "Content-Type" => "application/json"
20
21
  }.freeze
@@ -6,12 +6,15 @@ require 'active_support/core_ext/string/inflections'
6
6
  module Magellan
7
7
  module Cli
8
8
  class Command < Base
9
+ include Magellan::Cli::FileAccess
9
10
 
10
11
  {
12
+ "organization" => "Organization",
13
+ "team" => "Team",
11
14
  "project" => "Project",
12
15
  "stage" => "Stage",
13
16
  "client_version" => "ClientVersion",
14
- "function_unit" => "FunctionUnit",
17
+ "tr" => "TransactionRouter",
15
18
  "worker" => "WorkerVersion",
16
19
  "instance" => "HostInstance",
17
20
  "image" => "ContainerImage",
@@ -24,6 +27,15 @@ module Magellan
24
27
  desc "direct SUBCOMMAND ...ARGS", "send request directly"
25
28
  subcommand "direct", ::Magellan::Cli::Direct
26
29
 
30
+ desc "login", "login to a Magellan API server"
31
+ def login
32
+ print "email: "
33
+ email = STDIN.gets.chomp
34
+ print "password: "
35
+ password = STDIN.noecho(&:gets).chomp
36
+ puts ""
37
+ update_selections("login" => {"email" => email, "password" => password})
38
+ end
27
39
  end
28
40
  end
29
41
  end
@@ -0,0 +1,32 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Magellan
4
+ module Cli
5
+ module FileAccess
6
+
7
+ class NotSelected < StandardError
8
+ end
9
+
10
+ def load_selections
11
+ File.readable?(".magellan-cli") ? YAML.load_file(".magellan-cli") : {}
12
+ end
13
+
14
+ def load_selection(name)
15
+ sel = load_selections
16
+ s = sel[name]
17
+ raise NotSelected, "No #{name} selected" unless s
18
+ return s
19
+ end
20
+
21
+ def update_selections(hash = nil)
22
+ sel = load_selections
23
+ sel.update(hash) if hash
24
+ yield(sel) if block_given?
25
+ open(".magellan-cli", "w") do |f|
26
+ f.chmod 0600
27
+ YAML.dump(sel, f)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -16,12 +16,12 @@ module Magellan
16
16
  end
17
17
 
18
18
  # ログインしてGETします
19
- # @param [String] rel_path cli.base_https_url からの相対パス
19
+ # @param [String] rel_path cli.base_url からの相対パス
20
20
  # @param [Hash] params クエリ文字列
21
21
  # @return [Object] レスポンスのBODYをJSONとしてパースした結果オブジェクト
22
22
  def get_json(rel_path, params = nil)
23
23
  login do |cli|
24
- url = "#{cli.base_https_url}#{rel_path}"
24
+ url = "#{cli.base_url}#{rel_path}"
25
25
  if params && !params.empty?
26
26
  url << '?' << params.map{|k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
27
27
  end
@@ -32,7 +32,7 @@ module Magellan
32
32
  end
33
33
 
34
34
  # ログインしてPOSTします
35
- # @param [String] rel_path cli.base_https_url からの相対パス
35
+ # @param [String] rel_path cli.base_url からの相対パス
36
36
  # @param [Hash] params POSTで渡されるパラメータ
37
37
  # @return nil
38
38
  def post(rel_path, params)
@@ -43,7 +43,7 @@ module Magellan
43
43
  end
44
44
 
45
45
  # ログインしてJSON形式のbodyをPOSTします
46
- # @param [String] rel_path cli.base_https_url からの相対パス
46
+ # @param [String] rel_path cli.base_url からの相対パス
47
47
  # @param [Hash] params POSTで渡されるパラメータ
48
48
  # @return nil
49
49
  def post_json(rel_path, params)
@@ -54,7 +54,7 @@ module Magellan
54
54
  end
55
55
 
56
56
  # ログインしてPUTします
57
- # @param [String] rel_path cli.base_https_url からの相対パス
57
+ # @param [String] rel_path cli.base_url からの相対パス
58
58
  # @param [Hash] params PUTで渡されるパラメータ
59
59
  # @return nil
60
60
  def put(rel_path, params)
@@ -65,7 +65,7 @@ module Magellan
65
65
  end
66
66
 
67
67
  # ログインしてJSON形式のbodyをPUTします
68
- # @param [String] rel_path cli.base_https_url からの相対パス
68
+ # @param [String] rel_path cli.base_url からの相対パス
69
69
  # @param [Hash] params PUTで渡されるパラメータ
70
70
  # @return nil
71
71
  def put_json(rel_path, params)
@@ -76,7 +76,7 @@ module Magellan
76
76
  end
77
77
 
78
78
  # ログインしてDELETEします
79
- # @param [String] rel_path cli.base_https_url からの相対パス
79
+ # @param [String] rel_path cli.base_url からの相対パス
80
80
  # @return nil
81
81
  def delete(rel_path)
82
82
  login do |cli|
@@ -86,7 +86,7 @@ module Magellan
86
86
  end
87
87
 
88
88
  def process_res(cli, http_method, rel_path, *args)
89
- res = cli.httpclient.send(http_method, "#{cli.base_https_url}#{rel_path}", *args)
89
+ res = cli.httpclient.send(http_method, "#{cli.base_url}#{rel_path}", *args)
90
90
  case res.status
91
91
  when 200...300 then
92
92
  r = JSON.parse(res.body)
@@ -11,6 +11,7 @@ require 'active_support/core_ext/hash/keys'
11
11
  module Magellan
12
12
  module Cli
13
13
  class Login
14
+ include Magellan::Cli::FileAccess
14
15
 
15
16
  PRODUCTION_HTTP_PORT = 80
16
17
  PRODUCTION_HTTPS_PORT = 443
@@ -19,9 +20,7 @@ module Magellan
19
20
  DEFAULT_HTTPS_PORT = (ENV['DEFAULT_HTTPS_PORT'] || 443).to_i
20
21
 
21
22
  attr_reader :httpclient
22
- attr_reader :base_http_url
23
- attr_reader :base_https_url
24
- attr_reader :ssl_disabled
23
+ attr_reader :base_url
25
24
 
26
25
  attr_reader :auth_token
27
26
 
@@ -30,41 +29,29 @@ module Magellan
30
29
  # @param [String] base_url_or_host 接続先の基準となるURLあるいはホスト名
31
30
  # @param [Hash] options オプション
32
31
  # @option options [String] :api_version APIのバージョン。デフォルトは "1.0.0"
33
- # @option options [Boolean] :ssl_disabled SSLを無効にするかどうか。
34
- # @option options [Integer] :https_port HTTPSで接続する際の接続先のポート番号
35
32
  def initialize(base_url_or_host = nil, options = {})
36
33
  base_url_or_host ||= (ENV["MAGELLAN_SITE"] || "http://localhost:3000/")
37
34
  if base_url_or_host =~ URI.regexp
38
- @base_http_url = base_url_or_host.sub(/\/\Z/, '')
39
- uri = URI.parse(@base_http_url)
35
+ @base_url = base_url_or_host.sub(/\/\Z/, '')
36
+ uri = URI.parse(@base_url)
40
37
  else
41
38
  if config_path = search_file(".magellan-cli.yml")
42
39
  config = YAML.load_file_with_erb(config_path)
43
40
  options = config[base_url_or_host.to_s].deep_symbolize_keys.update(options)
44
41
  end
45
42
  uri = URI::Generic.build({scheme: "http", host: base_url_or_host, port: DEFAULT_HTTP_PORT}.update(options))
46
- @base_http_url = uri.to_s
43
+ @base_url = uri.to_s
47
44
  end
48
- @ssl_disabled = options.delete(:ssl_disabled)
49
- @ssl_disabled ||= (uri.port == 3000)
50
- @base_https_url = @ssl_disabled ? @base_http_url : build_https_url(uri, options[:https_port])
51
- # @api_version = options[:api_version] || "1.0.0"
52
45
 
53
46
  @httpclient = HTTPClient.new
54
47
  @httpclient.ssl_config.verify_mode = nil # 自己署名の証明書をOKにする
55
48
  end
56
49
 
57
- def build_https_url(uri, port = nil)
58
- uri.scheme = "https"
59
- uri.port = port || (uri.port == PRODUCTION_HTTP_PORT ? PRODUCTION_HTTPS_PORT : uri.port + 1)
60
- uri.to_s
61
- end
62
-
63
50
  def login_form_url
64
- @login_form_url ||= base_https_url + "/users/sign_in.html"
51
+ @login_form_url ||= base_url + "/users/sign_in.html"
65
52
  end
66
53
  def login_url
67
- @login_url ||= base_https_url + "/api/sign_in.json"
54
+ @login_url ||= base_url + "/api/sign_in.json"
68
55
  end
69
56
 
70
57
  # magellan-apiサーバに接続してログインの検証と処理を行います。
@@ -75,7 +62,7 @@ module Magellan
75
62
  def login_and_status
76
63
  @auth_token ||= get_auth_token
77
64
  params = {
78
- "user" => {"email" => "magellan@groovenauts.jp", "password" => "password"},
65
+ "user" => load_selection("login"),
79
66
  "authenticity_token" => @auth_token
80
67
  }.to_json
81
68
  res2 = Ssl.retry_on_ssl_error("login"){ @httpclient.post(login_url, params, JSON_HEADER) }
@@ -10,11 +10,13 @@ module Magellan
10
10
  module Resources
11
11
 
12
12
  autoload :Base , "magellan/cli/resources/base"
13
+ autoload :Organization , "magellan/cli/resources/organization"
14
+ autoload :Team , "magellan/cli/resources/team"
13
15
  autoload :Project , "magellan/cli/resources/project"
14
16
  autoload :Stage , "magellan/cli/resources/stage"
15
17
  autoload :ClientVersion , "magellan/cli/resources/client_version"
16
18
 
17
- autoload :FunctionUnit , "magellan/cli/resources/function_unit"
19
+ autoload :TransactionRouter, "magellan/cli/resources/transaction_router"
18
20
  autoload :WorkerVersion , "magellan/cli/resources/worker_version"
19
21
 
20
22
  autoload :HostInstance , "magellan/cli/resources/host_instance"
@@ -1,5 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require "magellan/cli/resources"
3
+ require "magellan/cli/file_access"
3
4
 
4
5
  require 'json'
5
6
  require 'yaml'
@@ -11,36 +12,14 @@ module Magellan
11
12
  module Cli
12
13
  module Resources
13
14
 
14
- class NotSelected < StandardError
15
- end
16
-
17
15
  class NotFound < StandardError
18
16
  end
19
17
 
20
18
  class Base < ::Magellan::Cli::Http
19
+ include Magellan::Cli::FileAccess
21
20
 
22
21
  no_commands do
23
22
 
24
- def load_selections
25
- File.readable?(".magellan-cli") ? YAML.load_file(".magellan-cli") : {}
26
- end
27
-
28
- def load_selection(name)
29
- sel = load_selections
30
- s = sel[name]
31
- raise NotSelected, "No #{name} selected" unless s
32
- return s
33
- end
34
-
35
- def update_selections(hash = nil)
36
- sel = load_selections
37
- sel.update(hash) if hash
38
- yield(sel) if block_given?
39
- open(".magellan-cli", "w") do |f|
40
- YAML.dump(sel, f)
41
- end
42
- end
43
-
44
23
  def build_query(hash)
45
24
  @@no ||= 0
46
25
  r = {}
@@ -88,7 +67,7 @@ module Magellan
88
67
 
89
68
  def select(name)
90
69
  q = build_query("name" => name).update(default_query)
91
- update_first_result(self.class.resource_name, "/admin/#{self.class.resource_name}.json", q)
70
+ update_first_result(self.class.parameter_name, "/admin/#{self.class.resource_name}.json", q)
92
71
  end
93
72
 
94
73
  def deselect
@@ -104,6 +83,12 @@ module Magellan
104
83
  no_commands do
105
84
  cattr_accessor :resource_name
106
85
  cattr_accessor :resource_dependency
86
+ def self.parameter_name
87
+ resource_name.gsub(/~/, "_")
88
+ end
89
+ def parameter_name
90
+ self.class.parameter_name
91
+ end
107
92
  end
108
93
 
109
94
  desc "list", "list #{base_name}"
@@ -8,6 +8,18 @@ module Magellan
8
8
  class ClientVersion < Base
9
9
  self.resource_name = "client_version"
10
10
  self.resource_dependency = {"stage" => "stage"}
11
+
12
+ desc "create VERSION", "create New Client Version"
13
+ def create(version)
14
+ stage = load_selection("stage")
15
+ params = {
16
+ parameter_name => {
17
+ "stage_title_id" => stage["id"],
18
+ "version" => version,
19
+ }
20
+ }
21
+ post_json("/admin/#{resource_name}/new.js", params)
22
+ end
11
23
  end
12
24
 
13
25
  end
@@ -6,6 +6,8 @@ module Magellan
6
6
  module Resources
7
7
 
8
8
  class ContainerImage < Base
9
+ self.resource_name = "container~image"
10
+ self.resource_dependency = {"stage" => "stage-version"}
9
11
  end
10
12
 
11
13
  end
@@ -6,18 +6,8 @@ module Magellan
6
6
  module Resources
7
7
 
8
8
  class ContainerInstance < Base
9
- self.resource_name = "container_instance"
10
- self.resource_dependency = {"host" => "host_instance"}
11
-
12
- desc "start ID", "start container instance specified by ID"
13
- def start(id)
14
- post_json("/admin/container_instance/#{id}/status_control.json", {})
15
- end
16
-
17
- desc "stop ID", "stop container instance specified by ID"
18
- def stop(id)
19
- delete("/admin/container_instance/#{id}/status_control.json")
20
- end
9
+ self.resource_name = "container~instance"
10
+ self.resource_dependency = {"stage" => "stage-version"}
21
11
  end
22
12
 
23
13
  end
@@ -6,12 +6,19 @@ module Magellan
6
6
  module Resources
7
7
 
8
8
  class HostInstance < Base
9
- self.resource_name = "host_instance"
10
- self.resource_dependency = {"stage" => "stage-version"}
11
-
12
- desc "sample_launch_options", "dump sample launch_options for create"
13
- def sample_launch_options
14
- $stdout.puts File.read(File.expand_path("../sample_launch_options.json", __FILE__))
9
+ self.resource_name = "vm~instance"
10
+ self.resource_dependency = {"stage" => "stage"}
11
+
12
+ desc "list", "list instances"
13
+ def list
14
+ stage_id = load_selection("stage")["id"] rescue nil
15
+ r = ""
16
+ if stage_id
17
+ r = get_json("/admin/stage~title/#{stage_id}/instance_list.json", {})
18
+ else
19
+ r = get_json("/admin/vm~instance.json")
20
+ end
21
+ $stdout.puts(JSON.pretty_generate(r) << "\nTotal: #{r.length}")
15
22
  end
16
23
 
17
24
  desc "create NAME [LAUNCH_OPTIONS]", "create Host Instance"
@@ -26,29 +33,9 @@ module Magellan
26
33
  "launch_options_yaml" => YAML.dump(launch_options),
27
34
  }
28
35
  }
29
- post_json("/admin/host_instance/new.js", params)
30
- end
31
-
32
- desc "launch", "launch host instance"
33
- def launch
34
- id = load_selection(self.class.resource_name)["id"]
35
- post_json("/admin/host_instance/#{id}/status_control.json", {})
36
- end
37
-
38
- desc "prepare", "prepare host instance"
39
- def prepare
40
- id = load_selection(self.class.resource_name)["id"]
41
- put_json("/admin/host_instance/#{id}/status_control.json", {})
36
+ post_json("/admin/vm~instance/new.js", params)
42
37
  end
43
38
 
44
- desc "stop", "stop host instance"
45
- def stop
46
- id = load_selection(self.class.resource_name)["id"]
47
- delete("/admin/host_instance/#{id}/status_control.json")
48
- end
49
-
50
-
51
-
52
39
  end
53
40
 
54
41
  end
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "magellan/cli/resources"
3
+
4
+ module Magellan
5
+ module Cli
6
+ module Resources
7
+
8
+ class Organization < Base
9
+ self.resource_name = "magellan~auth~organization"
10
+
11
+ desc "create NAME", "create Organization with NAME"
12
+ def create(name)
13
+ params = {
14
+ parameter_name => {
15
+ "name" => name,
16
+ }
17
+ }
18
+ post_json("/admin/#{self.resource_name}/new.js", params)
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -13,7 +13,19 @@ module Magellan
13
13
  def update(attrs)
14
14
  s = load_selection("project")
15
15
  attrs = JSON.parse(File.readable?(attrs) ? File.read(attrs) : attrs)
16
- put_json("/admin/magellan~auth~project/#{s['id']}/edit", {"magellan_auth_project" => attrs})
16
+ put_json("/admin/project/#{s['id']}/edit", {"project" => attrs})
17
+ end
18
+
19
+ desc "create NAME", "create new project with NAME"
20
+ def create(name)
21
+ o = load_selection(Organization.parameter_name)
22
+ params = {
23
+ parameter_name => {
24
+ "organization_id" => o["id"],
25
+ "name" => name,
26
+ }
27
+ }
28
+ post_json("/admin/#{resource_name}/new.js", params)
17
29
  end
18
30
  end
19
31
 
@@ -10,6 +10,24 @@ module Magellan
10
10
  self.resource_name = "stage~title"
11
11
  self.resource_dependency = {"project" => "project"}
12
12
 
13
+ desc "create NAME [-t development|staging|production|other]", "create Stage with Name and Type"
14
+ option :t, type: :string, default: "development", desc: "-t development|staging|production. specify Stage Type"
15
+ def create(name)
16
+ type = options["t"]
17
+ unless %w{ development staging production other }.include?(type)
18
+ raise "Unknown Stage Type #{type}"
19
+ end
20
+ proj = load_selection("project")
21
+ params = {
22
+ parameter_name => {
23
+ "project_id" => proj["id"],
24
+ "name" => name,
25
+ "stage_type" => type,
26
+ }
27
+ }
28
+ post_json("/admin/#{resource_name}/new.js", params)
29
+ end
30
+
13
31
  desc "select NAME", "select Stage named by NAME"
14
32
  def select(name)
15
33
  q = build_query("name" => name).update(default_query)
@@ -62,6 +80,18 @@ module Magellan
62
80
  id = s["id"]
63
81
  post_json("/admin/stage~title/#{id}/simple_method_call.json", {method_name: "release_now"})
64
82
  end
83
+
84
+ desc "logs", "fetch worker logs"
85
+ def logs
86
+ s = load_selection("stage")
87
+ id = s["id"]
88
+ obj = get_json("/admin/stage~title/#{id}/logs.json")
89
+ if obj["value"]
90
+ obj["value"].each do |log|
91
+ puts "#{Time.at(log["time"]).strftime("%Y-%m-%d %H:%M:%S")}:#{log["version"]}:#{log["container"]}: #{log["message"]}"
92
+ end
93
+ end
94
+ end
65
95
  end
66
96
 
67
97
  end
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "magellan/cli/resources"
3
+
4
+ module Magellan
5
+ module Cli
6
+ module Resources
7
+
8
+ class Team < Base
9
+ self.resource_name = "magellan~auth~team"
10
+ self.resource_dependency = { "organization" => Organization.parameter_name }
11
+
12
+ desc "create NAME ROLE", "create Team with NAME ROLE"
13
+ def create(name, role)
14
+ unless %w{ readers admin }.include?(role)
15
+ raise "ROLE should be 'readers' or 'admin'"
16
+ end
17
+ o = load_selection(Organization.parameter_name)
18
+ params = {
19
+ parameter_name => {
20
+ "organization_id" => o["id"],
21
+ "name" => name,
22
+ "role" => role,
23
+ }
24
+ }
25
+ post_json("/admin/#{self.resource_name}/new.js", params)
26
+ end
27
+
28
+ =begin
29
+ desc "invite EMAIL", "invite a user to the Team"
30
+ def invite(email)
31
+ o = load_selection(parameter_name)
32
+ params = {
33
+ "email" => email
34
+ }
35
+ post_json("/admin/#{self.resource_name}/#{o["id"]}/team_invite.json", params)
36
+ end
37
+ =end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "magellan/cli/resources"
3
+
4
+ module Magellan
5
+ module Cli
6
+ module Resources
7
+
8
+ class TransactionRouter < Base
9
+ self.resource_name = "functions~transaction_router"
10
+ self.resource_dependency = {"stage" => Stage.parameter_name}
11
+
12
+ desc "create NAME", "create TransactionRouter with NAME"
13
+ def create(name)
14
+ s = load_selection("stage-version")
15
+ params = {
16
+ self.class.parameter_name => {
17
+ "stage_version_id" => s["id"],
18
+ "name" => name,
19
+ # "instance_base_name" => name,
20
+ }
21
+ }
22
+ post_json("/admin/#{self.resource_name}/new.js", params)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -6,7 +6,7 @@ module Magellan
6
6
  module Resources
7
7
 
8
8
  class WorkerVersion < Base
9
- self.resource_name = "worker_version"
9
+ self.resource_name = "functions~worker"
10
10
  self.resource_dependency = {"stage" => "stage-version"}
11
11
 
12
12
  desc "create NAME, IMAGE", "create WorkerVersion with NAME, IMAGE"
@@ -20,18 +20,14 @@ module Magellan
20
20
  {}
21
21
  end
22
22
  params = {
23
- "worker_version" => {
23
+ "functions_worker" => {
24
24
  "stage_version_id" => s["id"],
25
+ "name" => name,
25
26
  "image_name" => image_name,
26
27
  # "instance_base_name" => name,
27
- "function_unit_attributes" => { # accepts_nested_attributes_for
28
- "name" => name,
29
- "kind" => "201",
30
- "stage_version_id" => s["id"],
31
- }
32
28
  }.update(attrs)
33
29
  }
34
- post_json("/admin/worker_version/new.js", params)
30
+ post_json("/admin/#{self.resource_name}/new.js", params)
35
31
  end
36
32
 
37
33
  end
@@ -1,5 +1,5 @@
1
1
  module Magellan
2
2
  module Cli
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -4,13 +4,20 @@ require 'spec_helper'
4
4
  describe Magellan::Cli::Login do
5
5
 
6
6
  describe :login! do
7
+ let(:email){ "magellan@groovenauts.jp" }
8
+ let(:password){ "password" }
7
9
  let(:auth_token){ "047bcCC1dnyVE+7DWE6YKIJF97L/qHk1mPrf2oaqWtE=" }
8
10
 
11
+ before do
12
+ allow(File).to receive(:readable?).and_return(true)
13
+ allow(YAML).to receive(:load_file).with(".magellan-cli").and_return({"login" => {"email" => email, "password" => password} })
14
+ end
15
+
9
16
  context :production do
10
- let(:cli){ Magellan::Cli::Login.new("http://example.com") }
17
+ let(:cli){ Magellan::Cli::Login.new("https://example.com") }
11
18
  before do
12
19
  res = double(:res)
13
- allow(cli.httpclient).to receive(:get).with("https://example.com:443/users/sign_in.html").and_return(res)
20
+ allow(cli.httpclient).to receive(:get).with("https://example.com/users/sign_in.html").and_return(res)
14
21
  allow(res).to receive(:status).and_return(200)
15
22
  allow(res).to receive(:body).and_return(File.read(File.expand_path("../login_page.html", __FILE__)))
16
23
  allow(res).to receive(:body_encoding).and_return(Encoding.find("UTF-8"))
@@ -18,14 +25,14 @@ describe Magellan::Cli::Login do
18
25
 
19
26
  let(:params) do
20
27
  {
21
- "user" => {"email" => "magellan@groovenauts.jp", "password" => "password"},
28
+ "user" => {"email" => email, "password" => password},
22
29
  "authenticity_token" => auth_token,
23
30
  }
24
31
  end
25
32
 
26
33
  it :login_success do
27
34
  res = double(:res)
28
- allow(cli.httpclient).to receive(:post).with("https://example.com:443/api/sign_in.json", params.to_json, Magellan::Cli::JSON_HEADER).and_return(res)
35
+ allow(cli.httpclient).to receive(:post).with("https://example.com/api/sign_in.json", params.to_json, Magellan::Cli::JSON_HEADER).and_return(res)
29
36
  allow(res).to receive(:status).and_return(200)
30
37
  allow(res).to receive(:body).and_return({"success" => true}.to_json)
31
38
  allow(res).to receive(:body_encoding).and_return(Encoding.find("UTF-8"))
@@ -34,13 +41,40 @@ describe Magellan::Cli::Login do
34
41
 
35
42
  it :login_failure do
36
43
  res = double(:res)
37
- allow(cli.httpclient).to receive(:post).with("https://example.com:443/api/sign_in.json", params.to_json, Magellan::Cli::JSON_HEADER).and_return(res)
44
+ allow(cli.httpclient).to receive(:post).with("https://example.com/api/sign_in.json", params.to_json, Magellan::Cli::JSON_HEADER).and_return(res)
38
45
  allow(res).to receive(:status).and_return(401) # Unauthorized
39
46
  allow(res).to receive(:body).and_return({"success" => false, "message" => "Error with your login or password"}.to_json)
40
47
  allow(res).to receive(:body_encoding).and_return(Encoding.find("UTF-8"))
41
48
  expect{cli.login!}.to raise_error(Magellan::Cli::LoginError, 'status: 401 {"success":false,"message":"Error with your login or password"}')
42
49
  end
43
50
  end
51
+
52
+ context :development do
53
+ let(:cli){ Magellan::Cli::Login.new("http://localhost:3001") }
54
+ before do
55
+ res = double(:res)
56
+ allow(cli.httpclient).to receive(:get).with("http://localhost:3001/users/sign_in.html").and_return(res)
57
+ allow(res).to receive(:status).and_return(200)
58
+ allow(res).to receive(:body).and_return(File.read(File.expand_path("../login_page.html", __FILE__)))
59
+ allow(res).to receive(:body_encoding).and_return(Encoding.find("UTF-8"))
60
+ end
61
+
62
+ let(:params) do
63
+ {
64
+ "user" => {"email" => email, "password" => password},
65
+ "authenticity_token" => auth_token,
66
+ }
67
+ end
68
+
69
+ it :login_success do
70
+ res = double(:res)
71
+ allow(cli.httpclient).to receive(:post).with("http://localhost:3001/api/sign_in.json", params.to_json, Magellan::Cli::JSON_HEADER).and_return(res)
72
+ allow(res).to receive(:status).and_return(200)
73
+ allow(res).to receive(:body).and_return({"success" => true}.to_json)
74
+ allow(res).to receive(:body_encoding).and_return(Encoding.find("UTF-8"))
75
+ expect(cli.login!).to eq cli # 自身を返す
76
+ end
77
+ end
44
78
  end
45
79
 
46
80
  end
@@ -0,0 +1,43 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Magellan::Cli::Resources::ClientVersion do
5
+
6
+ let(:cmd){ Magellan::Cli::Resources::ClientVersion.new }
7
+
8
+ describe :list do
9
+ before do
10
+ expect(cmd).to receive(:load_selections).and_return({"stage" => {"id" => "1", "name" => "StageA"} })
11
+ 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
+ expect($stdout).to receive(:puts)
13
+ end
14
+ it do
15
+ cmd.list
16
+ end
17
+ end
18
+
19
+ describe :create do
20
+ describe :success do
21
+ before do
22
+ expect(cmd).to receive(:load_selections).and_return({"stage" => {"id" => 1, "name" => "StageA"}})
23
+ expect(cmd).to receive(:post_json).with("/admin/client_version/new.js", { "client_version" => { "stage_title_id" => 1, "version" => "1.1.0" } })
24
+ end
25
+ it do
26
+ cmd.create("1.1.0")
27
+ end
28
+ end
29
+ describe :error do
30
+ context "stage not selected" do
31
+ before do
32
+ expect(cmd).to receive(:load_selections).and_return({})
33
+ end
34
+ it do
35
+ expect{
36
+ cmd.create("1.1.0")
37
+ }.to raise_error(Magellan::Cli::FileAccess::NotSelected)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Magellan::Cli::Resources::Organization do
5
+
6
+ let(:cmd){ Magellan::Cli::Resources::Organization.new }
7
+
8
+ describe :list do
9
+ before do
10
+ expect(cmd).to receive(:get_json).and_return([{id: 1, name: "org1", creator_id: 1}])
11
+ expect($stdout).to receive(:puts)
12
+ end
13
+ it do
14
+ cmd.list
15
+ end
16
+ end
17
+
18
+ describe :create do
19
+ before do
20
+ expect(cmd).to receive(:post_json).with("/admin/magellan~auth~organization/new.js", {"magellan_auth_organization" => { "name" => "new1" }})
21
+ end
22
+ it do
23
+ cmd.create("new1")
24
+ end
25
+ end
26
+
27
+ end
@@ -6,7 +6,7 @@ describe Magellan::Cli::Resources::Project do
6
6
  let(:base_url){ "https://localhost:3000" }
7
7
  let(:httpclient){ double(:httpclient) }
8
8
  let(:cli) do
9
- cli = double(:login, base_https_url: base_url)
9
+ cli = double(:login, base_url: base_url)
10
10
  allow(cli).to receive(:httpclient).and_return(httpclient)
11
11
  cli
12
12
  end
@@ -0,0 +1,50 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Magellan::Cli::Resources::Team do
5
+
6
+ let(:cmd){ Magellan::Cli::Resources::Team.new }
7
+
8
+ describe :list do
9
+ before do
10
+ expect(cmd).to receive(:load_selections).and_return({"magellan_auth_organization" => {"id" => "1", "name" => "testorg1"} })
11
+ expect(cmd).to receive(:get_json).and_return([{id: 1, organization_id: 1, name: "team1" }])
12
+ expect($stdout).to receive(:puts)
13
+ end
14
+ it do
15
+ cmd.list
16
+ end
17
+ end
18
+
19
+ describe :create do
20
+ describe :success do
21
+ before do
22
+ expect(cmd).to receive(:load_selection).with("magellan_auth_organization").and_return({"id" => 1, "name" => "org1"})
23
+ expect(cmd).to receive(:post_json).with("/admin/magellan~auth~team/new.js", { "magellan_auth_team" => { "organization_id" => 1, "name" => "team1", "role" => role } })
24
+ end
25
+ context "role=readers" do
26
+ let(:role){ "readers" }
27
+ it do
28
+ cmd.create("team1", role)
29
+ end
30
+ end
31
+ context "role=readers" do
32
+ let(:role){ "admin" }
33
+ it do
34
+ cmd.create("team1", role)
35
+ end
36
+ end
37
+ end
38
+ describe :error do
39
+ context "role=readers" do
40
+ let(:role){ "owners" }
41
+ it do
42
+ expect{
43
+ cmd.create("team1", role)
44
+ }.to raise_error(RuntimeError, /ROLE should be/)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ 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.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - akm2000
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-23 00:00:00.000000000 Z
11
+ date: 2014-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -131,6 +131,7 @@ files:
131
131
  - lib/magellan/cli/command.rb
132
132
  - lib/magellan/cli/direct.rb
133
133
  - lib/magellan/cli/errors.rb
134
+ - lib/magellan/cli/file_access.rb
134
135
  - lib/magellan/cli/http.rb
135
136
  - lib/magellan/cli/login.rb
136
137
  - lib/magellan/cli/resources.rb
@@ -138,10 +139,12 @@ files:
138
139
  - lib/magellan/cli/resources/client_version.rb
139
140
  - lib/magellan/cli/resources/container_image.rb
140
141
  - lib/magellan/cli/resources/container_instance.rb
141
- - lib/magellan/cli/resources/function_unit.rb
142
142
  - lib/magellan/cli/resources/host_instance.rb
143
+ - lib/magellan/cli/resources/organization.rb
143
144
  - lib/magellan/cli/resources/project.rb
144
145
  - lib/magellan/cli/resources/stage.rb
146
+ - lib/magellan/cli/resources/team.rb
147
+ - lib/magellan/cli/resources/transaction_router.rb
145
148
  - lib/magellan/cli/resources/worker_version.rb
146
149
  - lib/magellan/cli/sample_launch_options.json
147
150
  - lib/magellan/cli/ssl.rb
@@ -150,7 +153,10 @@ files:
150
153
  - spec/magellan/cli/Magellan.yml
151
154
  - spec/magellan/cli/login_page.html
152
155
  - spec/magellan/cli/login_spec.rb
156
+ - spec/magellan/cli/resources/client_version_spec.rb
157
+ - spec/magellan/cli/resources/organization_spec.rb
153
158
  - spec/magellan/cli/resources/project_spec.rb
159
+ - spec/magellan/cli/resources/team_spec.rb
154
160
  - spec/magellan/cli_spec.rb
155
161
  - spec/spec_helper.rb
156
162
  homepage: ''
@@ -181,7 +187,9 @@ test_files:
181
187
  - spec/magellan/cli/Magellan.yml
182
188
  - spec/magellan/cli/login_page.html
183
189
  - spec/magellan/cli/login_spec.rb
190
+ - spec/magellan/cli/resources/client_version_spec.rb
191
+ - spec/magellan/cli/resources/organization_spec.rb
184
192
  - spec/magellan/cli/resources/project_spec.rb
193
+ - spec/magellan/cli/resources/team_spec.rb
185
194
  - spec/magellan/cli_spec.rb
186
195
  - spec/spec_helper.rb
187
- has_rdoc:
@@ -1,27 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require "magellan/cli/resources"
3
-
4
- module Magellan
5
- module Cli
6
- module Resources
7
-
8
- class FunctionUnit < Base
9
- self.resource_name = "function_unit"
10
- self.resource_dependency = {"stage" => "stage-version"}
11
-
12
- desc "create [ATTRIBUTES]", "create FunctionUnit with ATTRIBUTES (filepath or JSON text)"
13
- def create(attrs = nil)
14
- stage_id = load_selection("stage-version")
15
- attrs = JSON.parse(File.readable?(attrs) ? File.read(attrs) : attrs)
16
- params = {
17
- "function_unit" => {
18
- "stage_version_id" => stage_id,
19
- }.update(attrs)
20
- }
21
- post_json("/admin/function_unit/new.js", params)
22
- end
23
- end
24
-
25
- end
26
- end
27
- end