tugboat 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +27 -2
  3. data/README.md +61 -0
  4. data/lib/tugboat/cli.rb +91 -4
  5. data/lib/tugboat/middleware.rb +54 -0
  6. data/lib/tugboat/middleware/check_droplet_active.rb +17 -0
  7. data/lib/tugboat/middleware/check_droplet_inactive.rb +17 -0
  8. data/lib/tugboat/middleware/find_droplet.rb +4 -0
  9. data/lib/tugboat/middleware/password_reset.rb +23 -0
  10. data/lib/tugboat/middleware/resize_droplet.rb +24 -0
  11. data/lib/tugboat/middleware/ssh_droplet.rb +4 -0
  12. data/lib/tugboat/middleware/start_droplet.rb +21 -0
  13. data/lib/tugboat/middleware/wait_for_state.rb +35 -0
  14. data/lib/tugboat/version.rb +1 -1
  15. data/spec/cli/authorize_cli_spec.rb +0 -4
  16. data/spec/cli/create_cli_spec.rb +0 -4
  17. data/spec/cli/destroy_cli_spec.rb +0 -4
  18. data/spec/cli/droplets_cli_spec.rb +1 -5
  19. data/spec/cli/halt_cli_spec.rb +16 -4
  20. data/spec/cli/help_cli_spec.rb +17 -0
  21. data/spec/cli/images_cli_spec.rb +0 -4
  22. data/spec/cli/info_cli_spec.rb +0 -4
  23. data/spec/cli/keys_cli_spec.rb +0 -4
  24. data/spec/cli/password_reset_cli_spec.rb +83 -0
  25. data/spec/cli/regions_cli_spec.rb +0 -4
  26. data/spec/cli/resize_cli_spec.rb +82 -0
  27. data/spec/cli/restart_cli_spec.rb +0 -4
  28. data/spec/cli/sizes_cli_spec.rb +0 -4
  29. data/spec/cli/snapshot_cli_spec.rb +18 -7
  30. data/spec/cli/ssh_cli_spec.rb +19 -4
  31. data/spec/cli/start_cli_spec.rb +76 -0
  32. data/spec/cli/version_cli_spec.rb +0 -4
  33. data/spec/cli/wait_cli_spec.rb +66 -0
  34. data/spec/config_spec.rb +2 -0
  35. data/spec/fixtures/show_droplet_inactive.json +13 -0
  36. data/spec/fixtures/show_droplets.json +1 -1
  37. data/spec/fixtures/show_droplets_inactive.json +35 -0
  38. data/spec/middleware/check_configuration_spec.rb +0 -3
  39. data/spec/middleware/check_credentials_spec.rb +0 -3
  40. data/spec/middleware/check_droplet_active_spec.rb +15 -0
  41. data/spec/middleware/check_droplet_inactive_spec.rb +15 -0
  42. data/spec/middleware/find_droplet_spec.rb +0 -3
  43. data/spec/middleware/inject_configuration_spec.rb +0 -3
  44. data/spec/middleware/ssh_droplet_spec.rb +19 -3
  45. data/spec/shared/environment.rb +3 -0
  46. data/spec/spec_helper.rb +5 -0
  47. data/tugboat.gemspec +2 -0
  48. metadata +42 -2
@@ -5,14 +5,10 @@ describe Tugboat::CLI do
5
5
 
6
6
  let(:snapshot_name) { "foo-snapshot" }
7
7
 
8
- before :each do
9
- @cli = Tugboat::CLI.new
10
- end
11
-
12
8
  describe "snapshots a droplet" do
13
9
  it "with a fuzzy name" do
14
10
  stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
15
- to_return(:status => 200, :body => fixture("show_droplets"))
11
+ to_return(:status => 200, :body => fixture("show_droplets_inactive"))
16
12
 
17
13
  stub_request(:get, "https://api.digitalocean.com/droplets/100823/snapshot?api_key=#{api_key}&client_id=#{client_key}&name=#{snapshot_name}").
18
14
  to_return(:status => 200, :body => fixture("show_droplet"))
@@ -31,7 +27,7 @@ Queuing snapshot 'foo-snapshot' for 100823 (foo)...done
31
27
 
32
28
  it "with an id" do
33
29
  stub_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}").
34
- to_return(:status => 200, :body => fixture("show_droplet"))
30
+ to_return(:status => 200, :body => fixture("show_droplet_inactive"))
35
31
 
36
32
  stub_request(:get, "https://api.digitalocean.com/droplets/100823/snapshot?api_key=#{api_key}&client_id=#{client_key}&name=#{snapshot_name}").
37
33
  to_return(:status => 200, :body => fixture("show_droplet"))
@@ -52,7 +48,7 @@ Queuing snapshot 'foo-snapshot' for 100823 (foo)...done
52
48
 
53
49
  it "with a name" do
54
50
  stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
55
- to_return(:status => 200, :body => fixture("show_droplets"))
51
+ to_return(:status => 200, :body => fixture("show_droplets_inactive"))
56
52
 
57
53
  stub_request(:get, "https://api.digitalocean.com/droplets/100823/snapshot?api_key=#{api_key}&client_id=#{client_key}&name=#{snapshot_name}").
58
54
  to_return(:status => 200, :body => fixture("show_droplet"))
@@ -70,6 +66,21 @@ Queuing snapshot 'foo-snapshot' for 100823 (foo)...done
70
66
  expect(a_request(:get, "https://api.digitalocean.com/droplets/100823/snapshot?api_key=#{api_key}&client_id=#{client_key}&name=#{snapshot_name}")).to have_been_made
71
67
  end
72
68
 
69
+ it "does not snaphshot a droplet that is active" do
70
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
71
+ to_return(:status => 200, :body => fixture("show_droplets"))
72
+
73
+ @cli.options = @cli.options.merge(:name => droplet_name)
74
+ expect {@cli.snapshot(snapshot_name)}.to raise_error(SystemExit)
75
+
76
+ expect($stdout.string).to eq <<-eos
77
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)
78
+ Droplet must be off for this operation to be successful.
79
+ eos
80
+
81
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
82
+ end
83
+
73
84
  end
74
85
 
75
86
  end
@@ -3,10 +3,6 @@ require 'spec_helper'
3
3
  describe Tugboat::CLI do
4
4
  include_context "spec"
5
5
 
6
- before :each do
7
- @cli = Tugboat::CLI.new
8
- end
9
-
10
6
  describe "ssh" do
11
7
  it "tries to fetch the droplet's IP from the API" do
12
8
  stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
@@ -18,5 +14,24 @@ describe Tugboat::CLI do
18
14
  expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).
19
15
  to have_been_made
20
16
  end
17
+
18
+ it "does not allow ssh into a droplet that is inactive" do
19
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
20
+ to_return(:status => 200, :body => fixture("show_droplets_inactive"))
21
+
22
+ Kernel.stub(:exec)
23
+
24
+ @cli.options = @cli.options.merge(:name => droplet_name)
25
+
26
+ expect {@cli.ssh("test222")}.to raise_error(SystemExit)
27
+
28
+ expect($stdout.string).to eq <<-eos
29
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)
30
+ Droplet must be on for this operation to be successful.
31
+ eos
32
+
33
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
34
+ end
35
+
21
36
  end
22
37
  end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ describe "start" do
7
+ it "starts the droplet with a fuzzy name" do
8
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
9
+ to_return(:status => 200, :body => fixture("show_droplets_inactive"))
10
+ stub_request(:put, "https://api.digitalocean.com/droplets/100823/power_on?api_key=#{api_key}&client_id=#{client_key}").
11
+ to_return(:status => 200, :body => fixture("show_droplet"))
12
+
13
+ @cli.start("foo")
14
+
15
+ expect($stdout.string).to eq <<-eos
16
+ Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 100823 (foo)
17
+ Queuing start for 100823 (foo)...done
18
+ eos
19
+
20
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
21
+ expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/power_on?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
22
+ end
23
+
24
+ it "starts the droplet with an id" do
25
+ stub_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}").
26
+ to_return(:status => 200, :body => fixture("show_droplet_inactive"))
27
+ stub_request(:put, "https://api.digitalocean.com/droplets/100823/power_on?api_key=#{api_key}&client_id=#{client_key}").
28
+ to_return(:status => 200, :body => fixture("show_droplet"))
29
+
30
+ @cli.options = @cli.options.merge(:id => droplet_id)
31
+ @cli.start
32
+
33
+ expect($stdout.string).to eq <<-eos
34
+ Droplet id provided. Finding Droplet...done\e[0m, 100823 (foo)
35
+ Queuing start for 100823 (foo)...done
36
+ eos
37
+
38
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
39
+ expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/power_on?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
40
+ end
41
+
42
+
43
+ it "starts the droplet with a name" do
44
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
45
+ to_return(:status => 200, :body => fixture("show_droplets_inactive"))
46
+ stub_request(:put, "https://api.digitalocean.com/droplets/100823/power_on?api_key=#{api_key}&client_id=#{client_key}").
47
+ to_return(:status => 200, :body => fixture("show_droplet"))
48
+
49
+ @cli.options = @cli.options.merge(:name => droplet_name)
50
+ @cli.start
51
+
52
+ expect($stdout.string).to eq <<-eos
53
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)
54
+ Queuing start for 100823 (foo)...done
55
+ eos
56
+
57
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
58
+ expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/power_on?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
59
+ end
60
+
61
+ it "does not start a droplet that is inactive" do
62
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
63
+ to_return(:status => 200, :body => fixture("show_droplets"))
64
+
65
+ @cli.options = @cli.options.merge(:name => droplet_name)
66
+ expect {@cli.start}.to raise_error(SystemExit)
67
+
68
+ expect($stdout.string).to eq <<-eos
69
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)
70
+ Droplet must be off for this operation to be successful.
71
+ eos
72
+
73
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
74
+ end
75
+ end
76
+ end
@@ -3,10 +3,6 @@ require 'spec_helper'
3
3
  describe Tugboat::CLI do
4
4
  include_context "spec"
5
5
 
6
- before :each do
7
- @cli = Tugboat::CLI.new
8
- end
9
-
10
6
  describe "version" do
11
7
  it "shows the correct version" do
12
8
 
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ describe "wait" do
7
+ it "waits for a droplet with a fuzzy name" do
8
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
9
+ to_return(:status => 200, :body => fixture("show_droplets"))
10
+
11
+ stub_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}").
12
+ to_return(:status => 200, :body => fixture("show_droplet"))
13
+
14
+ @cli.options = @cli.options.merge(:state => "active")
15
+ @cli.wait("foo")
16
+
17
+ expect($stdout.string).to eq <<-eos
18
+ Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 100823 (foo)
19
+ Waiting for droplet to become active..done\e[0m (0s)
20
+ eos
21
+
22
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
23
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
24
+ end
25
+
26
+ it "waits for a droplet with an id" do
27
+ stub_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}").
28
+ to_return(:status => 200, :body => fixture("show_droplet"))
29
+
30
+ stub_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}").
31
+ to_return(:status => 200, :body => fixture("show_droplet"))
32
+
33
+ @cli.options = @cli.options.merge(:id => droplet_id, :state => "active")
34
+ @cli.wait
35
+
36
+ expect($stdout.string).to eq <<-eos
37
+ Droplet id provided. Finding Droplet...done\e[0m, 100823 (foo)
38
+ Waiting for droplet to become active..done\e[0m (0s)
39
+ eos
40
+
41
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
42
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
43
+ end
44
+
45
+ it "waits for a droplet with a name" do
46
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
47
+ to_return(:status => 200, :body => fixture("show_droplets"))
48
+
49
+ stub_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}").
50
+ to_return(:status => 200, :body => fixture("show_droplet"))
51
+
52
+ @cli.options = @cli.options.merge(:name => droplet_name, :state => "active")
53
+ @cli.wait
54
+
55
+ expect($stdout.string).to eq <<-eos
56
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)
57
+ Waiting for droplet to become active..done\e[0m (0s)
58
+ eos
59
+
60
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
61
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Tugboat::Configuration do
4
+ include_context "spec"
5
+
4
6
  let(:tmp_path) { project_path + "/tmp/tugboat" }
5
7
 
6
8
  after :each do
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "OK",
3
+ "droplet": {
4
+ "backups_active": null,
5
+ "id": 100823,
6
+ "image_id": 420,
7
+ "name": "foo",
8
+ "ip_address": "33.33.33.10",
9
+ "region_id": 1,
10
+ "size_id": 33,
11
+ "status": "off"
12
+ }
13
+ }
@@ -29,7 +29,7 @@
29
29
  "name": "foo",
30
30
  "region_id": 1,
31
31
  "size_id": 33,
32
- "status": "off"
32
+ "status": "active"
33
33
  }
34
34
  ]
35
35
  }
@@ -0,0 +1,35 @@
1
+ {
2
+ "status": "OK",
3
+ "droplets": [
4
+ {
5
+ "ip_address": "33.33.33.10",
6
+ "backups_active": null,
7
+ "id": 100823,
8
+ "image_id": 420,
9
+ "name": "test222",
10
+ "region_id": 1,
11
+ "size_id": 33,
12
+ "status": "off"
13
+ },
14
+ {
15
+ "ip_address": "33.33.33.10",
16
+ "backups_active": null,
17
+ "id": 100823,
18
+ "image_id": 420,
19
+ "name": "test223",
20
+ "region_id": 1,
21
+ "size_id": 33,
22
+ "status": "off"
23
+ },
24
+ {
25
+ "ip_address": "33.33.33.10",
26
+ "backups_active": null,
27
+ "id": 100823,
28
+ "image_id": 420,
29
+ "name": "foo",
30
+ "region_id": 1,
31
+ "size_id": 33,
32
+ "status": "off"
33
+ }
34
+ ]
35
+ }
@@ -3,9 +3,6 @@ require 'spec_helper'
3
3
  describe Tugboat::Middleware::CheckConfiguration do
4
4
  include_context "spec"
5
5
 
6
- let(:app) { lambda { |env| } }
7
- let(:env) { {} }
8
-
9
6
  describe ".call" do
10
7
  it "raises SystemExit with no configuration" do
11
8
 
@@ -3,9 +3,6 @@ require 'spec_helper'
3
3
  describe Tugboat::Middleware::CheckCredentials do
4
4
  include_context "spec"
5
5
 
6
- let(:app) { lambda { |env| } }
7
- let(:env) { {} }
8
-
9
6
  describe ".call" do
10
7
  it "raises SystemExit with no configuration" do
11
8
  stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::Middleware::CheckDropletActive do
4
+ include_context "spec"
5
+
6
+ describe ".call" do
7
+ it "raises an error when droplet is not active" do
8
+
9
+ env["droplet_status"] = "off"
10
+
11
+ expect {described_class.new(app).call(env) }.to raise_error(SystemExit)
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::Middleware::CheckDropletInactive do
4
+ include_context "spec"
5
+
6
+ describe ".call" do
7
+ it "raises an error when droplet is active" do
8
+
9
+ env["droplet_status"] = "active"
10
+
11
+ expect {described_class.new(app).call(env) }.to raise_error(SystemExit)
12
+ end
13
+ end
14
+
15
+ end
@@ -3,9 +3,6 @@ require 'spec_helper'
3
3
  describe Tugboat::Middleware::FindDroplet do
4
4
  include_context "spec"
5
5
 
6
- let(:app) { lambda { |env| } }
7
- let(:env) { {} }
8
-
9
6
  describe ".call" do
10
7
  it "raises SystemExit with no droplet data" do
11
8
  expect {described_class.new(app).call(env) }.to raise_error(SystemExit)
@@ -3,9 +3,6 @@ require 'spec_helper'
3
3
  describe Tugboat::Middleware::InjectConfiguration do
4
4
  include_context "spec"
5
5
 
6
- let(:app) { lambda { |env| } }
7
- let(:env) { {} }
8
-
9
6
  describe ".call" do
10
7
 
11
8
  it "loads the configuration into the environment" do
@@ -3,9 +3,6 @@ require 'spec_helper'
3
3
  describe Tugboat::Middleware::SSHDroplet do
4
4
  include_context "spec"
5
5
 
6
- let(:app) { lambda { |env| } }
7
- let(:env) { {} }
8
-
9
6
  before do
10
7
  Kernel.stub!(:exec)
11
8
  end
@@ -28,6 +25,25 @@ describe Tugboat::Middleware::SSHDroplet do
28
25
  described_class.new(app).call(env)
29
26
  end
30
27
 
28
+ it "executes ssh with custom options" do
29
+ Kernel.should_receive(:exec).with("ssh",
30
+ "-o", "IdentitiesOnly=yes",
31
+ "-o", "LogLevel=ERROR",
32
+ "-o", "StrictHostKeyChecking=no",
33
+ "-o", "UserKnownHostsFile=/dev/null",
34
+ "-i", ssh_key_path,
35
+ "-p", ssh_port,
36
+ "-q",
37
+ "-X",
38
+ "#{ssh_user}@#{droplet_ip}")
39
+
40
+ env["droplet_ip"] = droplet_ip
41
+ env["config"] = config
42
+ env["user_droplet_ssh_opts"] = "-q -X"
43
+
44
+ described_class.new(app).call(env)
45
+ end
46
+
31
47
  end
32
48
 
33
49
  end
@@ -12,11 +12,14 @@ shared_context "spec" do
12
12
  let(:droplet_ip) { "33.33.33.10" }
13
13
  let(:droplet_id) { 1234 }
14
14
  let(:ocean) { DigitalOcean::API.new :client_id => client_key, :api_key =>api_key }
15
+ let(:app) { lambda { |env| } }
16
+ let(:env) { {} }
15
17
 
16
18
  before(:each) do
17
19
  $stdout.sync = true
18
20
  $stderr.sync = true
19
21
 
22
+ @cli = Tugboat::CLI.new
20
23
 
21
24
  # Set a temprary project path and create fake config.
22
25
  config.create_config_file(client_key, api_key, ssh_key_path, ssh_user, ssh_port)
@@ -1,3 +1,6 @@
1
+ require 'coveralls'
2
+ Coveralls.wear! { add_filter '/spec/' }
3
+
1
4
  require 'tugboat'
2
5
  require 'webmock/rspec'
3
6
  require 'digital_ocean'
@@ -6,6 +9,8 @@ require "shared/environment"
6
9
  RSpec.configure do |config|
7
10
  # Pretty tests
8
11
  config.color_enabled = true
12
+
13
+ config.order = :random
9
14
  end
10
15
 
11
16
  def project_path