tugboat 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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