tugboat 0.0.5 → 0.0.6

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.
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