tugboat 0.0.4 → 0.0.5

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 (36) hide show
  1. data/.travis.yml +5 -0
  2. data/CHANGELOG.md +29 -5
  3. data/CONTRIBUTING.md +22 -0
  4. data/README.md +1 -0
  5. data/bin/tugboat +6 -0
  6. data/lib/tugboat/cli.rb +26 -1
  7. data/lib/tugboat/middleware.rb +22 -0
  8. data/lib/tugboat/middleware/check_configuration.rb +1 -1
  9. data/lib/tugboat/middleware/check_credentials.rb +1 -1
  10. data/lib/tugboat/middleware/confirm_action.rb +1 -1
  11. data/lib/tugboat/middleware/create_droplet.rb +1 -1
  12. data/lib/tugboat/middleware/destroy_droplet.rb +1 -1
  13. data/lib/tugboat/middleware/find_droplet.rb +5 -5
  14. data/lib/tugboat/middleware/halt_droplet.rb +8 -4
  15. data/lib/tugboat/middleware/info_droplet.rb +1 -1
  16. data/lib/tugboat/middleware/list_regions.rb +17 -0
  17. data/lib/tugboat/middleware/list_sizes.rb +17 -0
  18. data/lib/tugboat/middleware/restart_droplet.rb +8 -4
  19. data/lib/tugboat/middleware/snapshot_droplet.rb +1 -1
  20. data/lib/tugboat/middleware/ssh_droplet.rb +2 -1
  21. data/lib/tugboat/version.rb +1 -1
  22. data/spec/cli/halt_cli_spec.rb +18 -0
  23. data/spec/cli/regions_cli_spec.rb +28 -0
  24. data/spec/cli/restart_cli_spec.rb +18 -0
  25. data/spec/cli/sizes_cli_spec.rb +28 -0
  26. data/spec/cli/ssh_cli_spec.rb +22 -0
  27. data/spec/fixtures/show_regions.json +17 -0
  28. data/spec/fixtures/show_sizes.json +17 -0
  29. data/spec/middleware/check_configuration_spec.rb +19 -0
  30. data/spec/middleware/check_credentials_spec.rb +23 -0
  31. data/spec/middleware/find_droplet_spec.rb +15 -0
  32. data/spec/middleware/ssh_droplet_spec.rb +33 -0
  33. data/spec/shared/environment.rb +4 -2
  34. data/spec/spec_helper.rb +1 -0
  35. data/tugboat.gemspec +0 -1
  36. metadata +23 -18
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ - 2.0.0
@@ -1,4 +1,28 @@
1
- ## 0.0.4 (unreleased)
1
+ ## 0.0.5 (unreleased)
2
+
3
+ FEATURES:
4
+
5
+ - [Ørjan](https://github.com/blom) added a `regions` command, which
6
+ returns a list of available DigitalOcean regions. You can specify
7
+ which region to use while creating: `tugboat create foobar -r 2`. [GH-18]
8
+ - [Ørjan](https://github.com/blom) added an ssh_user option to the
9
+ `ssh` command. This lets you specify the user to connect as on
10
+ a per-command basis, as well as in your `.tugboat`.
11
+ - [Ørjan](https://github.com/blom) added a `sizes` command, which
12
+ returns a list of available sizes. You can specify which size to
13
+ use while creating: `tugboat create foobar -s 66` [GH-19]
14
+ - [Ørjan](https://github.com/blom) added a `hard` flag to
15
+ `halt` and `restart`. This cycles the Droplet's power. `tugboat restart --hard` [GH-27]
16
+
17
+ IMPROVEMENTS:
18
+
19
+ - Tugboat now returns proper status codes for successes and failures.
20
+ [GH-21]
21
+ - Support for MRI 1.8.7
22
+ - CTRL+C's, SIG-INT's are now caught and quietly kill Tugboat without
23
+ a stacktrace.
24
+
25
+ ## 0.0.4 (April 23, 2013)
2
26
 
3
27
  BUG FIXES:
4
28
 
@@ -15,13 +39,13 @@ IMPROVEMENTS:
15
39
  - [Ørjan](https://github.com/blom) added a `--version` command to see
16
40
  what version of Tugboat you're using.
17
41
  - Substantially more test coverage - all of the commands (except `ssh` are
18
- now unit tested. [GH-15]
42
+ now integration tested. [GH-15]
19
43
 
20
44
  FEATURES:
21
45
 
22
- - Optionally add a list of ssh_key_ids when creating a droplet. These
23
- SSH keys will automatically be added to your droplet.
24
- - Show a list of SSH keys on your account with `tugboat keys`
46
+ - Optionally add a list of ssh_key_ids when creating a droplet. These
47
+ SSH keys will automatically be added to your droplet.
48
+ - Show a list of SSH keys on your account with `tugboat keys`
25
49
  - [Phil](https://github.com/PhilETaylor) added the ability to specify
26
50
  an `--ssh-port` on `tugboat ssh`, as well as set a default in your `.tugboat` [GH-13]
27
51
 
@@ -5,3 +5,25 @@
5
5
  3. Commit your changes (`git commit -am 'Add some feature'`)
6
6
  4. Push to the branch (`git push origin my-new-feature`)
7
7
  5. Create new Pull Request
8
+
9
+
10
+ ## Development Environment
11
+
12
+ To add a feature, fix a bug, or to run a development build of Tugboat
13
+ on your machine, clone down the repo and run:
14
+
15
+ $ bundle
16
+
17
+ You can then execute tugboat:
18
+
19
+ $ bundle exec tugboat [command]
20
+
21
+ As well as run the tests:
22
+
23
+ $ bundle exec rspec
24
+
25
+ To install the gem on your system from source:
26
+
27
+ $ bundle exec rake install
28
+
29
+ If you need help with your environment, feel free to open an issue.
data/README.md CHANGED
@@ -17,6 +17,7 @@ Run the configuration utility, `tugboat authorize`. You can grab your keys
17
17
  Enter your API key: bar
18
18
  Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa):
19
19
  Enter your SSH user (optional, defaults to jack):
20
+ Enter your SSH port number (optional, defaults to 22):
20
21
  Authentication with DigitalOcean was successful!
21
22
 
22
23
  ## Usage
@@ -1,4 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
+
3
+ # https://github.com/mitchellh/vagrant/blob/8cc4910fa9ca6059697459d0cdee1557af8d0507/bin/vagrant#L3-L6
4
+ # Catch any ctrl+c's to avoid stack traces. Thanks Mitchell. ^^
5
+
6
+ Signal.trap("INT") { exit 1 }
7
+
2
8
  require "tugboat"
3
9
 
4
10
  Tugboat::CLI.start(ARGV)
@@ -64,12 +64,17 @@ module Tugboat
64
64
  :type => :string,
65
65
  :aliases => "-p",
66
66
  :desc => "The custom SSH Port to connect to"
67
+ method_option "ssh_user",
68
+ :type => :string,
69
+ :aliases => "-u",
70
+ :desc => "Specifies which user to log in as"
67
71
  def ssh(name=nil)
68
72
  Middleware.sequence_ssh_droplet.call({
69
73
  "user_droplet_id" => options[:id],
70
74
  "user_droplet_name" => options[:name],
71
75
  "user_droplet_fuzzy_name" => name,
72
- "user_droplet_ssh_port" => options[:ssh_port]
76
+ "user_droplet_ssh_port" => options[:ssh_port],
77
+ "user_droplet_ssh_user" => options[:ssh_user]
73
78
  })
74
79
  end
75
80
 
@@ -134,10 +139,15 @@ module Tugboat
134
139
  :type => :string,
135
140
  :aliases => "-n",
136
141
  :desc => "The exact name of the droplet"
142
+ method_option "hard",
143
+ :type => :boolean,
144
+ :aliases => "-h",
145
+ :desc => "Perform a hard restart"
137
146
  def restart(name=nil)
138
147
  Middleware.sequence_restart_droplet.call({
139
148
  "user_droplet_id" => options[:id],
140
149
  "user_droplet_name" => options[:name],
150
+ "user_droplet_hard" => options[:hard],
141
151
  "user_droplet_fuzzy_name" => name
142
152
  })
143
153
  end
@@ -151,10 +161,15 @@ module Tugboat
151
161
  :type => :string,
152
162
  :aliases => "-n",
153
163
  :desc => "The exact name of the droplet"
164
+ method_option "hard",
165
+ :type => :boolean,
166
+ :aliases => "-h",
167
+ :desc => "Perform a hard shutdown"
154
168
  def halt(name=nil)
155
169
  Middleware.sequence_halt_droplet.call({
156
170
  "user_droplet_id" => options[:id],
157
171
  "user_droplet_name" => options[:name],
172
+ "user_droplet_hard" => options[:hard],
158
173
  "user_droplet_fuzzy_name" => name
159
174
  })
160
175
  end
@@ -199,10 +214,20 @@ module Tugboat
199
214
  Middleware.sequence_ssh_keys.call({})
200
215
  end
201
216
 
217
+ desc "regions", "Show regions"
218
+ def regions
219
+ Middleware.sequence_regions.call({})
220
+ end
221
+
202
222
  desc "version", "Show version"
203
223
  def version
204
224
  say "Tugboat #{Tugboat::VERSION}"
205
225
  end
226
+
227
+ desc "sizes", "Show available droplet sizes"
228
+ def sizes
229
+ Middleware.sequence_sizes.call({})
230
+ end
206
231
  end
207
232
  end
208
233
 
@@ -20,6 +20,8 @@ module Tugboat
20
20
  autoload :SnapshotDroplet, "tugboat/middleware/snapshot_droplet"
21
21
  autoload :ListImages, "tugboat/middleware/list_images"
22
22
  autoload :ListSSHKeys, "tugboat/middleware/list_ssh_keys"
23
+ autoload :ListRegions, "tugboat/middleware/list_regions"
24
+ autoload :ListSizes, "tugboat/middleware/list_sizes"
23
25
 
24
26
  # Start the authorization flow.
25
27
  # This writes a ~/.tugboat file, which can be edited manually.
@@ -140,5 +142,25 @@ module Tugboat
140
142
  use ListSSHKeys
141
143
  end
142
144
  end
145
+
146
+ # Display a list of regions
147
+ def self.sequence_regions
148
+ ::Middleware::Builder.new do
149
+ use InjectConfiguration
150
+ use CheckConfiguration
151
+ use InjectClient
152
+ use ListRegions
153
+ end
154
+ end
155
+
156
+ # Display a list of droplet sizes
157
+ def self.sequence_sizes
158
+ ::Middleware::Builder.new do
159
+ use InjectConfiguration
160
+ use CheckConfiguration
161
+ use InjectClient
162
+ use ListSizes
163
+ end
164
+ end
143
165
  end
144
166
  end
@@ -7,7 +7,7 @@ module Tugboat
7
7
 
8
8
  if !config || !config.data || !config.api_key || !config.client_key
9
9
  say "You must run `tugboat authorize` in order to connect to DigitalOcean", :red
10
- return
10
+ exit 1
11
11
  end
12
12
 
13
13
  @app.call(env)
@@ -11,7 +11,7 @@ module Tugboat
11
11
  env["ocean"].droplets.list
12
12
  rescue Faraday::Error::ParsingError
13
13
  say "Authentication with DigitalOcean failed. Run `tugboat authorize`", :red
14
- return
14
+ exit 1
15
15
  end
16
16
 
17
17
  say "Authentication with DigitalOcean was successful.", :green
@@ -9,7 +9,7 @@ module Tugboat
9
9
  if !response
10
10
  say "Aborted due to user request.", :red
11
11
  # Quit
12
- return
12
+ exit 1
13
13
  end
14
14
 
15
15
  end
@@ -14,7 +14,7 @@ module Tugboat
14
14
 
15
15
  if req.status == "ERROR"
16
16
  say req.error_message, :red
17
- return
17
+ exit 1
18
18
  end
19
19
 
20
20
  say "done", :green
@@ -10,7 +10,7 @@ module Tugboat
10
10
 
11
11
  if req.status == "ERROR"
12
12
  say "#{req.status}: #{req.error_message}", :red
13
- return
13
+ exit 1
14
14
  end
15
15
 
16
16
  say "done", :green
@@ -12,7 +12,7 @@ module Tugboat
12
12
  # let the user know.
13
13
  if !user_fuzzy_name && !user_droplet_name && !user_droplet_id
14
14
  say "Tugboat attempted to find a droplet with no arguments. Try `tugboat help`", :red
15
- return
15
+ exit 1
16
16
  end
17
17
 
18
18
  # If you were to `tugboat restart foo -n foo-server-001` then we'd use
@@ -27,7 +27,7 @@ module Tugboat
27
27
 
28
28
  if req.status == "ERROR"
29
29
  say "#{req.status}: #{req.error_message}", :red
30
- return
30
+ exit 1
31
31
  end
32
32
 
33
33
  env["droplet_id"] = req.droplet.id
@@ -52,8 +52,8 @@ module Tugboat
52
52
  # If we coulnd't find it, tell the user and drop out of the
53
53
  # sequence.
54
54
  if !env["droplet_id"]
55
- say "Unable to find a droplet named '#{user_droplet_name}'.", :red
56
- return
55
+ say "error\nUnable to find a droplet named '#{user_droplet_name}'.", :red
56
+ exit 1
57
57
  end
58
58
  end
59
59
 
@@ -102,7 +102,7 @@ module Tugboat
102
102
  # sequence.
103
103
  if !env["droplet_id"]
104
104
  say "error\nUnable to find a droplet named '#{user_fuzzy_name}'.", :red
105
- return
105
+ exit 1
106
106
  end
107
107
  end
108
108
 
@@ -4,13 +4,17 @@ module Tugboat
4
4
  def call(env)
5
5
  ocean = env["ocean"]
6
6
 
7
- say "Queuing shutdown for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
8
-
9
- req = ocean.droplets.shutdown env["droplet_id"]
7
+ req = if env["user_droplet_hard"]
8
+ say "Queuing hard shutdown for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
9
+ ocean.droplets.power_off env["droplet_id"]
10
+ else
11
+ say "Queuing shutdown for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
12
+ ocean.droplets.shutdown env["droplet_id"]
13
+ end
10
14
 
11
15
  if req.status == "ERROR"
12
16
  say req.error_message, :red
13
- return
17
+ exit 1
14
18
  end
15
19
 
16
20
  say "done", :green
@@ -8,7 +8,7 @@ module Tugboat
8
8
 
9
9
  if req.status == "ERROR"
10
10
  say "#{req.status}: #{req.error_message}", :red
11
- return
11
+ exit 1
12
12
  end
13
13
 
14
14
  droplet = req.droplet
@@ -0,0 +1,17 @@
1
+ module Tugboat
2
+ module Middleware
3
+ class ListRegions < Base
4
+ def call(env)
5
+ ocean = env["ocean"]
6
+ regions = ocean.regions.list.regions
7
+
8
+ say "Regions:"
9
+ regions.each do |region|
10
+ say "#{region.name} (id: #{region.id})"
11
+ end
12
+
13
+ @app.call(env)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Tugboat
2
+ module Middleware
3
+ class ListSizes < Base
4
+ def call(env)
5
+ ocean = env["ocean"]
6
+ sizes = ocean.sizes.list.sizes
7
+
8
+ say "Sizes:"
9
+ sizes.each do |size|
10
+ say "#{size.name} (id: #{size.id})"
11
+ end
12
+
13
+ @app.call(env)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -4,13 +4,17 @@ module Tugboat
4
4
  def call(env)
5
5
  ocean = env["ocean"]
6
6
 
7
- say "Queuing restart for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
8
-
9
- req = ocean.droplets.reboot env["droplet_id"]
7
+ req = if env["user_droplet_hard"]
8
+ say "Queuing hard restart for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
9
+ ocean.droplets.power_cycle env["droplet_id"]
10
+ else
11
+ say "Queuing restart for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
12
+ ocean.droplets.reboot env["droplet_id"]
13
+ end
10
14
 
11
15
  if req.status == "ERROR"
12
16
  say "#{req.status}: #{req.error_message}", :red
13
- return
17
+ exit 1
14
18
  end
15
19
 
16
20
  say "done", :green
@@ -15,7 +15,7 @@ module Tugboat
15
15
 
16
16
  if req.status == "ERROR"
17
17
  say "#{req.status}: #{req.error_message}", :red
18
- return
18
+ exit 1
19
19
  end
20
20
 
21
21
  say "done", :green
@@ -19,7 +19,8 @@ module Tugboat
19
19
  options.push("-p", "22")
20
20
  end
21
21
 
22
- host_string = "#{env["config"].ssh_user}@#{env["droplet_ip"]}"
22
+ ssh_user = env["user_droplet_ssh_user"] || env["config"].ssh_user
23
+ host_string = "#{ssh_user}@#{env["droplet_ip"]}"
23
24
 
24
25
  options << host_string
25
26
 
@@ -1,3 +1,3 @@
1
1
  module Tugboat
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -26,6 +26,24 @@ Queuing shutdown for 100823 (foo)...done
26
26
  expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/shutdown?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
27
27
  end
28
28
 
29
+ it "halts a droplet hard when the hard option is used" do
30
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
31
+ to_return(:status => 200, :body => fixture("show_droplets"))
32
+ stub_request(:put, "https://api.digitalocean.com/droplets/100823/power_off?api_key=#{api_key}&client_id=#{client_key}").
33
+ to_return(:status => 200, :body => fixture("show_droplet"))
34
+
35
+ @cli.options = @cli.options.merge(:hard => true)
36
+ @cli.halt("foo")
37
+
38
+ expect($stdout.string).to eq <<-eos
39
+ Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 100823 (foo)
40
+ Queuing hard shutdown for 100823 (foo)...done
41
+ eos
42
+
43
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
44
+ expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/power_off?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
45
+ end
46
+
29
47
  it "halts a droplet with an id" do
30
48
  stub_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}").
31
49
  to_return(:status => 200, :body => fixture("show_droplet"))
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "regions" do
11
+ it "shows a list" do
12
+ stub_request(:get, "https://api.digitalocean.com/regions?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200, :body => fixture("show_regions"))
14
+
15
+ @cli.regions
16
+
17
+ expect($stdout.string).to eq <<-eos
18
+ Regions:
19
+ Region 1 (id: 1)
20
+ Region 2 (id: 2)
21
+ Region 3 (id: 3)
22
+ eos
23
+
24
+ expect(a_request(:get, "https://api.digitalocean.com/regions?api_key=#{api_key}&client_id=#{client_key}")).
25
+ to have_been_made
26
+ end
27
+ end
28
+ end
@@ -26,6 +26,24 @@ Queuing restart for 100823 (foo)...done
26
26
  expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/reboot?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
27
27
  end
28
28
 
29
+ it "restarts a droplet hard when the hard option is used" do
30
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
31
+ to_return(:status => 200, :body => fixture("show_droplets"))
32
+ stub_request(:put, "https://api.digitalocean.com/droplets/100823/power_cycle?api_key=#{api_key}&client_id=#{client_key}").
33
+ to_return(:status => 200, :body => fixture("show_droplet"))
34
+
35
+ @cli.options = @cli.options.merge(:hard => true)
36
+ @cli.restart("foo")
37
+
38
+ expect($stdout.string).to eq <<-eos
39
+ Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 100823 (foo)
40
+ Queuing hard restart for 100823 (foo)...done
41
+ eos
42
+
43
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
44
+ expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/power_cycle?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
45
+ end
46
+
29
47
  it "with an id" do
30
48
  stub_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}").
31
49
  to_return(:status => 200, :body => fixture("show_droplet"))
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "sizes" do
11
+ it "shows a list" do
12
+ stub_request(:get, "https://api.digitalocean.com/sizes?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200, :body => fixture("show_sizes"))
14
+
15
+ @cli.sizes
16
+
17
+ expect($stdout.string).to eq <<-eos
18
+ Sizes:
19
+ Size 1 (id: 1)
20
+ Size 2 (id: 2)
21
+ Size 3 (id: 3)
22
+ eos
23
+
24
+ expect(a_request(:get, "https://api.digitalocean.com/sizes?api_key=#{api_key}&client_id=#{client_key}")).
25
+ to have_been_made
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "ssh" do
11
+ it "tries to fetch the droplet's IP from the API" do
12
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200, :body => fixture("show_droplets"))
14
+ Kernel.stub(:exec)
15
+
16
+ @cli.ssh("test222")
17
+
18
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).
19
+ to have_been_made
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ {
2
+ "status": "OK",
3
+ "regions": [
4
+ {
5
+ "id": 1,
6
+ "name": "Region 1"
7
+ },
8
+ {
9
+ "id": 2,
10
+ "name": "Region 2"
11
+ },
12
+ {
13
+ "id": 3,
14
+ "name": "Region 3"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "status": "OK",
3
+ "sizes": [
4
+ {
5
+ "id": 1,
6
+ "name": "Size 1"
7
+ },
8
+ {
9
+ "id": 2,
10
+ "name": "Size 2"
11
+ },
12
+ {
13
+ "id": 3,
14
+ "name": "Size 3"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::Middleware::CheckConfiguration do
4
+ include_context "spec"
5
+
6
+ let(:app) { lambda { |env| } }
7
+ let(:env) { {} }
8
+
9
+ describe ".call" do
10
+ it "raises SystemExit with no configuration" do
11
+
12
+ # Delete the temp configuration file.
13
+ File.delete(project_path + "/tmp/tugboat")
14
+
15
+ expect {described_class.new(app).call(env) }.to raise_error(SystemExit)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::Middleware::CheckCredentials do
4
+ include_context "spec"
5
+
6
+ let(:app) { lambda { |env| } }
7
+ let(:env) { {} }
8
+
9
+ describe ".call" do
10
+ it "raises SystemExit with no configuration" do
11
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
12
+ to_return(:status => 200, :body => "<html>You are being redirected...</html>")
13
+
14
+ # Inject the client.
15
+ env["ocean"] = ocean
16
+
17
+ expect {described_class.new(app).call(env) }.to raise_error(SystemExit)
18
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).
19
+ to have_been_made
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::Middleware::FindDroplet do
4
+ include_context "spec"
5
+
6
+ let(:app) { lambda { |env| } }
7
+ let(:env) { {} }
8
+
9
+ describe ".call" do
10
+ it "raises SystemExit with no droplet data" do
11
+ expect {described_class.new(app).call(env) }.to raise_error(SystemExit)
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::Middleware::SSHDroplet do
4
+ include_context "spec"
5
+
6
+ let(:app) { lambda { |env| } }
7
+ let(:env) { {} }
8
+
9
+ before do
10
+ Kernel.stub!(:exec)
11
+ end
12
+
13
+ describe ".call" do
14
+
15
+ it "exec ssh with correct options" do
16
+ Kernel.should_receive(:exec).with("ssh",
17
+ "-o", "IdentitiesOnly=yes",
18
+ "-o", "LogLevel=ERROR",
19
+ "-o", "StrictHostKeyChecking=no",
20
+ "-o", "UserKnownHostsFile=/dev/null",
21
+ "-i", ssh_key_path,
22
+ "-p", ssh_port,
23
+ "#{ssh_user}@#{droplet_ip}")
24
+
25
+ env["droplet_ip"] = droplet_ip
26
+ env["config"] = config
27
+
28
+ described_class.new(app).call(env)
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -9,15 +9,17 @@ shared_context "spec" do
9
9
  let(:ssh_port) { "22" }
10
10
  let(:ssh_key_path) { "~/.ssh/id_rsa2" }
11
11
  let(:droplet_name) { "foo" }
12
+ let(:droplet_ip) { "33.33.33.10" }
12
13
  let(:droplet_id) { 1234 }
13
-
14
+ let(:ocean) { DigitalOcean::API.new :client_id => client_key, :api_key =>api_key }
14
15
 
15
16
  before(:each) do
16
17
  $stdout.sync = true
17
18
  $stderr.sync = true
18
19
 
20
+
19
21
  # Set a temprary project path and create fake config.
20
- config.create_config_file(client_key, api_key, ssh_user, ssh_key_path, ssh_port)
22
+ config.create_config_file(client_key, api_key, ssh_key_path, ssh_user, ssh_port)
21
23
  config.reload!
22
24
 
23
25
  # Keep track of the old stderr / out
@@ -1,5 +1,6 @@
1
1
  require 'tugboat'
2
2
  require 'webmock/rspec'
3
+ require 'digital_ocean'
3
4
  require "shared/environment"
4
5
 
5
6
  RSpec.configure do |config|
@@ -26,5 +26,4 @@ Gem::Specification.new do |gem|
26
26
  gem.add_development_dependency "rspec-expectations", "~> 2.13.0"
27
27
  gem.add_development_dependency "rspec-mocks", "~> 2.13.0"
28
28
  gem.add_development_dependency "webmock", "~> 1.11.0"
29
- gem.add_development_dependency "debugger", "~> 1.5.0"
30
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tugboat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-23 00:00:00.000000000 Z
12
+ date: 2013-05-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -139,22 +139,6 @@ dependencies:
139
139
  - - ~>
140
140
  - !ruby/object:Gem::Version
141
141
  version: 1.11.0
142
- - !ruby/object:Gem::Dependency
143
- name: debugger
144
- requirement: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ~>
148
- - !ruby/object:Gem::Version
149
- version: 1.5.0
150
- type: :development
151
- prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
- requirements:
155
- - - ~>
156
- - !ruby/object:Gem::Version
157
- version: 1.5.0
158
142
  description: A command line tool for interacting with your DigitalOcean droplets.
159
143
  email:
160
144
  - jackpearkes@gmail.com
@@ -164,6 +148,7 @@ extensions: []
164
148
  extra_rdoc_files: []
165
149
  files:
166
150
  - .gitignore
151
+ - .travis.yml
167
152
  - CHANGELOG.md
168
153
  - CONTRIBUTING.md
169
154
  - Gemfile
@@ -189,6 +174,8 @@ files:
189
174
  - lib/tugboat/middleware/inject_configuration.rb
190
175
  - lib/tugboat/middleware/list_droplets.rb
191
176
  - lib/tugboat/middleware/list_images.rb
177
+ - lib/tugboat/middleware/list_regions.rb
178
+ - lib/tugboat/middleware/list_sizes.rb
192
179
  - lib/tugboat/middleware/list_ssh_keys.rb
193
180
  - lib/tugboat/middleware/restart_droplet.rb
194
181
  - lib/tugboat/middleware/snapshot_droplet.rb
@@ -202,8 +189,11 @@ files:
202
189
  - spec/cli/images_cli_spec.rb
203
190
  - spec/cli/info_cli_spec.rb
204
191
  - spec/cli/keys_cli_spec.rb
192
+ - spec/cli/regions_cli_spec.rb
205
193
  - spec/cli/restart_cli_spec.rb
194
+ - spec/cli/sizes_cli_spec.rb
206
195
  - spec/cli/snapshot_cli_spec.rb
196
+ - spec/cli/ssh_cli_spec.rb
207
197
  - spec/cli/version_cli_spec.rb
208
198
  - spec/config_spec.rb
209
199
  - spec/fixtures/create_droplet.json
@@ -212,8 +202,14 @@ files:
212
202
  - spec/fixtures/show_images.json
213
203
  - spec/fixtures/show_images_global.json
214
204
  - spec/fixtures/show_keys.json
205
+ - spec/fixtures/show_regions.json
206
+ - spec/fixtures/show_sizes.json
215
207
  - spec/middleware/base_spec.rb
208
+ - spec/middleware/check_configuration_spec.rb
209
+ - spec/middleware/check_credentials_spec.rb
210
+ - spec/middleware/find_droplet_spec.rb
216
211
  - spec/middleware/inject_configuration_spec.rb
212
+ - spec/middleware/ssh_droplet_spec.rb
217
213
  - spec/shared/environment.rb
218
214
  - spec/spec_helper.rb
219
215
  - tmp/.gitkeep
@@ -251,8 +247,11 @@ test_files:
251
247
  - spec/cli/images_cli_spec.rb
252
248
  - spec/cli/info_cli_spec.rb
253
249
  - spec/cli/keys_cli_spec.rb
250
+ - spec/cli/regions_cli_spec.rb
254
251
  - spec/cli/restart_cli_spec.rb
252
+ - spec/cli/sizes_cli_spec.rb
255
253
  - spec/cli/snapshot_cli_spec.rb
254
+ - spec/cli/ssh_cli_spec.rb
256
255
  - spec/cli/version_cli_spec.rb
257
256
  - spec/config_spec.rb
258
257
  - spec/fixtures/create_droplet.json
@@ -261,7 +260,13 @@ test_files:
261
260
  - spec/fixtures/show_images.json
262
261
  - spec/fixtures/show_images_global.json
263
262
  - spec/fixtures/show_keys.json
263
+ - spec/fixtures/show_regions.json
264
+ - spec/fixtures/show_sizes.json
264
265
  - spec/middleware/base_spec.rb
266
+ - spec/middleware/check_configuration_spec.rb
267
+ - spec/middleware/check_credentials_spec.rb
268
+ - spec/middleware/find_droplet_spec.rb
265
269
  - spec/middleware/inject_configuration_spec.rb
270
+ - spec/middleware/ssh_droplet_spec.rb
266
271
  - spec/shared/environment.rb
267
272
  - spec/spec_helper.rb