tugboat 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: acb3d5fff3be496ee45a238c9219bea4c159ca4e
4
- data.tar.gz: a88aea864325b1d5b0e7d37642b42418e79ed905
3
+ metadata.gz: 2d849915ab2227a3a3ffa08de72535a611cfbd84
4
+ data.tar.gz: 62a801c0f5e32a631d290e05528f2805813d7f58
5
5
  SHA512:
6
- metadata.gz: e53bbe9b2bf1e3bd5bef1f748249857045da696f57e250b2819aa7261db9bdd769ed53b21e60258de6f1c5090e05de8906b0f47de4f313cacf62c20c74357c9a
7
- data.tar.gz: 0806ce448db80b8a5436c647f56e144a4b94394fbc866bc4a676cea6f45bed21d4b1649339c1b3f55ca13c462fa89b08f251b539ab92d3b4358405162a69181a
6
+ metadata.gz: 0248ef0e63f0b8d62ab68027740fc5ba22b31f5c9c20d7df711d51f6f4e3a35aa69369bf6dbaa677b3e3b0f421865133ea0bdca13e84a530f0c5520393d4a547
7
+ data.tar.gz: c1afc811c11f657f3821b2407164a63616368546c67f88f3eb67d14138c3eaf1ea00244132d0aa409f882467bf3f01a096ab6d7410ef12cb2efec8f51eb3d778
@@ -1,4 +1,23 @@
1
- ## 0.0.8 (Unreleased)
1
+ ## 0.0.9 (December 24, 2013)
2
+
3
+ FEATURES:
4
+
5
+ - [Pete](https://github.com/petems) added the ability to add an
6
+ ssh key to your account. [GH-64]
7
+ - [Caleb](https://github.com/calebreach) gave us an easy way
8
+ to pass a command through to a machine with the `-c` command. [GH-73]
9
+
10
+ IMPROVEMENTS:
11
+
12
+ - [Andrew](https://github.com/4n3w) added a private networking option. [GH-75]
13
+
14
+ BUG FIXES:
15
+
16
+ - [Zo](https://github.com/obradovic) made our default image 13.04 [GH-76]
17
+ - Issues with the JSON dependency in 2.0.0 were resolved. [GH-80]
18
+
19
+
20
+ ## 0.0.8 (September 7, 2013)
2
21
 
3
22
  FEATURES:
4
23
 
data/README.md CHANGED
@@ -24,7 +24,7 @@ Run the configuration utility, `tugboat authorize`. You can grab your keys
24
24
  Defaults can be changed at any time in your ~/.tugboat configuration file.
25
25
 
26
26
  Enter your default region ID (optional, defaults to 1 (New York)):
27
- Enter your default image ID (optional, defaults to 284203 (Ubuntu 12.04 x64)):
27
+ Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)):
28
28
  Enter your default size ID (optional, defaults to 66 (512MB)):
29
29
  Enter your default ssh key ID (optional, defaults to none):
30
30
 
@@ -188,6 +188,15 @@ ask tugboat about it.
188
188
  For a complete overview of all of the available commands, run:
189
189
 
190
190
  $ tugboat help
191
+
192
+
193
+ Depending on your local configuration, you may need to install a CA bundle (OS X only) using [homebrew](http://brew.sh/) to commmunicate with DigitalOcean through SSL/TLS:
194
+
195
+ $ brew install curl-ca-bundle
196
+
197
+ After installation, source the bundle path in your `.bash_profile`/`.bashrc`:
198
+
199
+ export SSL_CERT_FILE=/usr/local/opt/curl-ca-bundle/share/ca-bundle.crt
191
200
 
192
201
  ## Reporting Bugs
193
202
 
@@ -1,6 +1,7 @@
1
1
  require 'tugboat/cli'
2
2
  require "tugboat/config"
3
3
  require "tugboat/version"
4
+ require 'json'
4
5
 
5
6
  module Tugboat
6
7
  end
@@ -83,6 +83,10 @@ module Tugboat
83
83
  :type => :string,
84
84
  :aliases => "-o",
85
85
  :desc => "Custom SSH options"
86
+ method_option "ssh_command",
87
+ :type => :string,
88
+ :aliases => "-c",
89
+ :desc => "Command to run on the droplet"
86
90
  def ssh(name=nil)
87
91
  Middleware.sequence_ssh_droplet.call({
88
92
  "user_droplet_id" => options[:id],
@@ -90,7 +94,8 @@ module Tugboat
90
94
  "user_droplet_fuzzy_name" => name,
91
95
  "user_droplet_ssh_port" => options[:ssh_port],
92
96
  "user_droplet_ssh_user" => options[:ssh_user],
93
- "user_droplet_ssh_opts" => options[:ssh_opts]
97
+ "user_droplet_ssh_opts" => options[:ssh_opts],
98
+ "user_droplet_ssh_command" => options[:ssh_command]
94
99
  })
95
100
  end
96
101
 
@@ -111,12 +116,18 @@ module Tugboat
111
116
  :type => :string,
112
117
  :aliases => "-k",
113
118
  :desc => "A comma separated list of SSH key ids to add to the droplet"
119
+ method_option "private_networking",
120
+ :type => :boolean,
121
+ :aliases => "-p",
122
+ :desc => "Enable private networking on the droplet"
123
+
114
124
  def create(name)
115
125
  Middleware.sequence_create_droplet.call({
116
126
  "create_droplet_size_id" => options[:size],
117
127
  "create_droplet_image_id" => options[:image],
118
128
  "create_droplet_region_id" => options[:region],
119
129
  "create_droplet_ssh_key_ids" => options[:keys],
130
+ "create_droplet_private_networking" => options[:private_networking],
120
131
  "create_droplet_name" => name
121
132
  })
122
133
  end
@@ -227,6 +238,23 @@ module Tugboat
227
238
  Middleware.sequence_ssh_keys.call({})
228
239
  end
229
240
 
241
+ desc "add-key NAME", "Upload an ssh public key."
242
+ method_option "key",
243
+ :type => :string,
244
+ :aliases => "-k",
245
+ :desc => "The string of the key"
246
+ method_option "path",
247
+ :type => :string,
248
+ :aliases => "-p",
249
+ :desc => "The path to the ssh key"
250
+ def add_key(name)
251
+ Middleware.sequence_add_key.call({
252
+ "add_key_name" => name,
253
+ "add_key_pub_key" => options[:key],
254
+ "add_key_file_path" => options[:path],
255
+ })
256
+ end
257
+
230
258
  desc "regions", "Show regions"
231
259
  def regions
232
260
  Middleware.sequence_regions.call({})
@@ -13,9 +13,10 @@ module Tugboat
13
13
  DEFAULT_SSH_KEY_PATH = '.ssh/id_rsa'
14
14
  DEFAULT_SSH_PORT = '22'
15
15
  DEFAULT_REGION = '1'
16
- DEFAULT_IMAGE = '284203'
16
+ DEFAULT_IMAGE = '350076'
17
17
  DEFAULT_SIZE = '66'
18
18
  DEFAULT_SSH_KEY = ''
19
+ DEFAULT_PRIVATE_NETWORKING = 'false'
19
20
 
20
21
  def initialize
21
22
  @path = ENV["TUGBOAT_CONFIG_PATH"] || File.join(File.expand_path("~"), FILE_NAME)
@@ -67,6 +68,10 @@ module Tugboat
67
68
  @data['defaults'].nil? ? DEFAULT_SSH_KEY : @data['defaults']['ssh_key']
68
69
  end
69
70
 
71
+ def default_private_networking
72
+ @data['defaults'].nil? ? DEFAULT_PRIVATE_NETWORKING : @data['defaults']['private_networking']
73
+ end
74
+
70
75
  # Re-runs initialize
71
76
  def reset!
72
77
  self.send(:initialize)
@@ -78,7 +83,7 @@ module Tugboat
78
83
  end
79
84
 
80
85
  # Writes a config file
81
- def create_config_file(client, api, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key)
86
+ def create_config_file(client, api, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key, private_networking)
82
87
  # Default SSH Key path
83
88
  if ssh_key_path.empty?
84
89
  ssh_key_path = File.join(File.expand_path("~"), DEFAULT_SSH_KEY_PATH)
@@ -108,13 +113,28 @@ module Tugboat
108
113
  default_ssh_key = DEFAULT_SSH_KEY
109
114
  end
110
115
 
116
+ if private_networking.empty?
117
+ private_networking = DEFAULT_PRIVATE_NETWORKING
118
+ end
119
+
111
120
  require 'yaml'
112
121
  File.open(@path, File::RDWR|File::TRUNC|File::CREAT, 0600) do |file|
113
122
  data = {
114
- "authentication" => { "client_key" => client, "api_key" => api },
115
- "ssh" => { "ssh_user" => ssh_user, "ssh_key_path" => ssh_key_path , "ssh_port" => ssh_port},
116
- "defaults" => { "region" => region, "image" => image, "size" => size, "ssh_key" => ssh_key }
117
- }
123
+ "authentication" => {
124
+ "client_key" => client,
125
+ "api_key" => api },
126
+ "ssh" => {
127
+ "ssh_user" => ssh_user,
128
+ "ssh_key_path" => ssh_key_path ,
129
+ "ssh_port" => ssh_port },
130
+ "defaults" => {
131
+ "region" => region,
132
+ "image" => image,
133
+ "size" => size,
134
+ "ssh_key" => ssh_key,
135
+ "private_networking" => private_networking
136
+ }
137
+ }
118
138
  file.write data.to_yaml
119
139
  end
120
140
  end
@@ -2,31 +2,32 @@ require "middleware"
2
2
 
3
3
  module Tugboat
4
4
  module Middleware
5
+ autoload :AddKey, "tugboat/middleware/add_key"
6
+ autoload :AskForCredentials, "tugboat/middleware/ask_for_credentials"
5
7
  autoload :Base, "tugboat/middleware/base"
6
- autoload :InjectConfiguration, "tugboat/middleware/inject_configuration"
7
8
  autoload :CheckConfiguration, "tugboat/middleware/check_configuration"
8
- autoload :AskForCredentials, "tugboat/middleware/ask_for_credentials"
9
- autoload :InjectClient, "tugboat/middleware/inject_client"
10
9
  autoload :CheckCredentials, "tugboat/middleware/check_credentials"
11
- autoload :ListDroplets, "tugboat/middleware/list_droplets"
10
+ autoload :CheckDropletActive, "tugboat/middleware/check_droplet_active"
11
+ autoload :CheckDropletInactive, "tugboat/middleware/check_droplet_inactive"
12
+ autoload :ConfirmAction, "tugboat/middleware/confirm_action"
13
+ autoload :CreateDroplet, "tugboat/middleware/create_droplet"
14
+ autoload :DestroyDroplet, "tugboat/middleware/destroy_droplet"
12
15
  autoload :FindDroplet, "tugboat/middleware/find_droplet"
13
- autoload :RestartDroplet, "tugboat/middleware/restart_droplet"
14
- autoload :StartDroplet, "tugboat/middleware/start_droplet"
15
16
  autoload :HaltDroplet, "tugboat/middleware/halt_droplet"
16
17
  autoload :InfoDroplet, "tugboat/middleware/info_droplet"
17
- autoload :SSHDroplet, "tugboat/middleware/ssh_droplet"
18
- autoload :CreateDroplet, "tugboat/middleware/create_droplet"
19
- autoload :DestroyDroplet, "tugboat/middleware/destroy_droplet"
20
- autoload :ConfirmAction, "tugboat/middleware/confirm_action"
21
- autoload :SnapshotDroplet, "tugboat/middleware/snapshot_droplet"
22
- autoload :ResizeDroplet, "tugboat/middleware/resize_droplet"
18
+ autoload :InjectClient, "tugboat/middleware/inject_client"
19
+ autoload :InjectConfiguration, "tugboat/middleware/inject_configuration"
20
+ autoload :ListDroplets, "tugboat/middleware/list_droplets"
23
21
  autoload :ListImages, "tugboat/middleware/list_images"
24
- autoload :ListSSHKeys, "tugboat/middleware/list_ssh_keys"
25
22
  autoload :ListRegions, "tugboat/middleware/list_regions"
26
23
  autoload :ListSizes, "tugboat/middleware/list_sizes"
27
- autoload :CheckDropletActive, "tugboat/middleware/check_droplet_active"
28
- autoload :CheckDropletInactive, "tugboat/middleware/check_droplet_inactive"
24
+ autoload :ListSSHKeys, "tugboat/middleware/list_ssh_keys"
29
25
  autoload :PasswordReset, "tugboat/middleware/password_reset"
26
+ autoload :ResizeDroplet, "tugboat/middleware/resize_droplet"
27
+ autoload :RestartDroplet, "tugboat/middleware/restart_droplet"
28
+ autoload :SnapshotDroplet, "tugboat/middleware/snapshot_droplet"
29
+ autoload :SSHDroplet, "tugboat/middleware/ssh_droplet"
30
+ autoload :StartDroplet, "tugboat/middleware/start_droplet"
30
31
  autoload :WaitForState, "tugboat/middleware/wait_for_state"
31
32
 
32
33
  # Start the authorization flow.
@@ -174,6 +175,16 @@ module Tugboat
174
175
  end
175
176
  end
176
177
 
178
+ # Create a droplet
179
+ def self.sequence_add_key
180
+ ::Middleware::Builder.new do
181
+ use InjectConfiguration
182
+ use CheckConfiguration
183
+ use InjectClient
184
+ use AddKey
185
+ end
186
+ end
187
+
177
188
  # Display a list of regions
178
189
  def self.sequence_regions
179
190
  ::Middleware::Builder.new do
@@ -0,0 +1,47 @@
1
+ module Tugboat
2
+ module Middleware
3
+ class AddKey < Base
4
+ def call(env)
5
+ ocean = env["ocean"]
6
+
7
+ if env["add_key_pub_key"]
8
+ pub_key_string = env["add_key_pub_key"]
9
+ else
10
+ if env["add_key_file_path"]
11
+ pub_key_string = File.read(env["add_key_file_path"])
12
+ else
13
+ possible_keys = Dir.glob("#{ENV['HOME']}/.ssh/*.pub")
14
+
15
+ # Only show hinted keys if the user has any
16
+ if possible_keys.size > 0
17
+ say "Possible public key paths from #{ENV['HOME']}/.ssh:"
18
+ say
19
+ possible_keys.each do |key_file|
20
+ say "#{key_file}"
21
+ end
22
+ say
23
+ end
24
+
25
+ ssh_key_file = ask "Enter the path to your SSH key:"
26
+ pub_key_string = File.read("#{ssh_key_file}")
27
+ end
28
+ end
29
+
30
+ say "Queueing upload of SSH key '#{env["add_key_name"]}'...", nil, false
31
+
32
+ req = ocean.ssh_keys.add :name => env["add_key_name"],
33
+ :ssh_pub_key => pub_key_string
34
+
35
+ if req.status == "ERROR"
36
+ say req.error_message, :red
37
+ exit 1
38
+ end
39
+
40
+ say "done", :green
41
+
42
+ @app.call(env)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
@@ -15,12 +15,13 @@ module Tugboat
15
15
  say "Defaults can be changed at any time in your ~/.tugboat configuration file."
16
16
  say
17
17
  region = ask "Enter your default region ID (optional, defaults to 1 (New York)):"
18
- image = ask "Enter your default image ID (optional, defaults to 284203 (Ubuntu 12.04 x64)):"
18
+ image = ask "Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)):"
19
19
  size = ask "Enter your default size ID (optional, defaults to 66 (512MB)):"
20
20
  ssh_key = ask "Enter your default ssh key ID (optional, defaults to none):"
21
+ private_networking = ask "Enter your default for private networking (optional, defaults to false):"
21
22
 
22
23
  # Write the config file.
23
- env['config'].create_config_file(client_key, api_key, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key)
24
+ env['config'].create_config_file(client_key, api_key, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key, private_networking)
24
25
  env['config'].reload!
25
26
 
26
27
  @app.call(env)
@@ -22,11 +22,16 @@ module Tugboat
22
22
  droplet_ssh_key_id = env["create_droplet_ssh_key_ids"] :
23
23
  droplet_ssh_key_id = env["config"].default_ssh_key
24
24
 
25
- req = ocean.droplets.create :name => env["create_droplet_name"],
26
- :size_id => droplet_size_id,
27
- :image_id => droplet_image_id,
28
- :region_id => droplet_region_id,
29
- :ssh_key_ids => droplet_ssh_key_id
25
+ env["create_droplet_private_networking"] ?
26
+ droplet_private_networking = env["create_droplet_private_networking"] :
27
+ droplet_private_networking = env["config"].default_private_networking
28
+
29
+ req = ocean.droplets.create :name => env["create_droplet_name"],
30
+ :size_id => droplet_size_id,
31
+ :image_id => droplet_image_id,
32
+ :region_id => droplet_region_id,
33
+ :ssh_key_ids => droplet_ssh_key_id,
34
+ :private_networking => droplet_private_networking
30
35
 
31
36
  if req.status == "ERROR"
32
37
  say req.error_message, :red
@@ -28,6 +28,9 @@ module Tugboat
28
28
 
29
29
  options << host_string
30
30
 
31
+ if env["user_droplet_ssh_command"]
32
+ options.push(env["user_droplet_ssh_command"])
33
+ end
31
34
 
32
35
  Kernel.exec("ssh", *options)
33
36
 
@@ -1,3 +1,3 @@
1
1
  module Tugboat
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+
4
+ describe Tugboat::CLI do
5
+ include_context "spec"
6
+
7
+ let(:tmp_path) { project_path + "/tmp/tugboat" }
8
+ let(:fake_home) { "#{project_path}/tmp" }
9
+
10
+ before :each do
11
+ File.open("id_dsa.pub", 'w') {|f| f.write("ssh-dss A456= user@host") }
12
+ end
13
+
14
+ after :each do
15
+ File.delete("id_dsa.pub") if File.exist?("id_dsa.pub")
16
+ File.delete("#{fake_home}/.ssh/id_rsa.pub") if File.exist?("#{fake_home}/.ssh/id_rsa.pub")
17
+ end
18
+
19
+ describe "add-key" do
20
+ it "with a name and key string" do
21
+
22
+ stub_request(:get, "https://api.digitalocean.com/ssh_keys/new?api_key=#{api_key}&client_id=#{client_key}&name=#{ssh_key_name}&ssh_pub_key=#{ssh_public_key}").
23
+ to_return(:status => 200, :body => fixture("create_ssh_key"))
24
+
25
+ @cli.options = @cli.options.merge(:key => "#{ssh_public_key}")
26
+ @cli.add_key(ssh_key_name)
27
+
28
+ expect($stdout.string).to eq <<-eos
29
+ Queueing upload of SSH key '#{ssh_key_name}'...done
30
+ eos
31
+
32
+ expect(a_request(:get, "https://api.digitalocean.com/ssh_keys/new?api_key=#{api_key}&client_id=#{client_key}&name=#{ssh_key_name}&ssh_pub_key=#{ssh_public_key}")).to have_been_made
33
+ end
34
+
35
+ before :each do
36
+ ENV.stub(:[]).with('HOME').and_return(fake_home)
37
+ ENV.stub(:[]).with('DEBUG').and_return(nil)
38
+ ENV.stub(:[]).with('http_proxy').and_return(nil)
39
+ FileUtils.mkdir_p "#{fake_home}/.ssh"
40
+ File.open("#{fake_home}/.ssh/id_rsa.pub", 'w') {|f| f.write("ssh-dss A456= user@host") }
41
+ end
42
+
43
+ it "with name, prompts from file folder" do
44
+ stub_request(:get, "https://api.digitalocean.com/ssh_keys/new?api_key=#{api_key}&client_id=#{client_key}&name=#{ssh_key_name}&ssh_pub_key=ssh-dss%20A456=%20user@host").
45
+ to_return(:status => 200, :body => fixture("create_ssh_key"))
46
+
47
+ $stdout.should_receive(:print).exactly(4).times
48
+ $stdout.should_receive(:print).with("Enter the path to your SSH key: ")
49
+ $stdout.should_receive(:print).with("Queueing upload of SSH key '#{ssh_key_name}'...")
50
+ $stdin.should_receive(:gets).and_return("#{fake_home}/.ssh/id_rsa.pub")
51
+
52
+ @cli.add_key(ssh_key_name)
53
+
54
+ expect($stdout.string).to eq <<-eos
55
+ Possible public key paths from #{fake_home}/.ssh:
56
+
57
+ #{fake_home}/.ssh/id_rsa.pub
58
+
59
+ done
60
+ eos
61
+
62
+ expect(a_request(:get, "https://api.digitalocean.com/ssh_keys/new?api_key=#{api_key}&client_id=#{client_key}&name=#{ssh_key_name}&ssh_pub_key=ssh-dss%20A456=%20user@host")).to have_been_made
63
+ end
64
+
65
+ after :each do
66
+ File.delete("id_dsa.pub") if File.exist?("id_dsa.pub")
67
+ FileUtils.rm_rf("#{fake_home}/.ssh/") if File.exist?("#{fake_home}/.ssh/")
68
+ end
69
+
70
+ end
71
+ end
72
+
@@ -26,18 +26,20 @@ describe Tugboat::CLI do
26
26
  $stdin.should_receive(:gets).and_return(ssh_port)
27
27
  $stdout.should_receive(:print).with("Enter your default region ID (optional, defaults to 1 (New York)): ")
28
28
  $stdin.should_receive(:gets).and_return(region)
29
- $stdout.should_receive(:print).with("Enter your default image ID (optional, defaults to 284203 (Ubuntu 12.04 x64)): ")
29
+ $stdout.should_receive(:print).with("Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)): ")
30
30
  $stdin.should_receive(:gets).and_return(image)
31
31
  $stdout.should_receive(:print).with("Enter your default size ID (optional, defaults to 66 (512MB)): ")
32
32
  $stdin.should_receive(:gets).and_return(size)
33
33
  $stdout.should_receive(:print).with("Enter your default ssh key ID (optional, defaults to none): ")
34
34
  $stdin.should_receive(:gets).and_return(ssh_key_id)
35
+ $stdout.should_receive(:print).with("Enter your default for private networking (optional, defaults to false): ")
36
+ $stdin.should_receive(:gets).and_return(private_networking)
35
37
 
36
38
  @cli.authorize
37
39
 
38
40
  expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
39
41
 
40
- File.read(tmp_path).should include "image: '#{image}'", "region: '#{region}'", "size: '#{size}'", "ssh_user: #{ssh_user}", "ssh_key_path: #{ssh_key_path}", "ssh_port: '#{ssh_port}'", "ssh_key: '#{ssh_key_id}'"
42
+ File.read(tmp_path).should include "image: '#{image}'", "region: '#{region}'", "size: '#{size}'", "ssh_user: #{ssh_user}", "ssh_key_path: #{ssh_key_path}", "ssh_port: '#{ssh_port}'", "ssh_key: '#{ssh_key_id}'", "private_networking: '#{private_networking}'"
41
43
 
42
44
  end
43
45
 
@@ -56,18 +58,20 @@ describe Tugboat::CLI do
56
58
  $stdin.should_receive(:gets).and_return('')
57
59
  $stdout.should_receive(:print).with("Enter your default region ID (optional, defaults to 1 (New York)): ")
58
60
  $stdin.should_receive(:gets).and_return('')
59
- $stdout.should_receive(:print).with("Enter your default image ID (optional, defaults to 284203 (Ubuntu 12.04 x64)): ")
61
+ $stdout.should_receive(:print).with("Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)): ")
60
62
  $stdin.should_receive(:gets).and_return('')
61
63
  $stdout.should_receive(:print).with("Enter your default size ID (optional, defaults to 66 (512MB)): ")
62
64
  $stdin.should_receive(:gets).and_return('')
63
65
  $stdout.should_receive(:print).with("Enter your default ssh key ID (optional, defaults to none): ")
64
66
  $stdin.should_receive(:gets).and_return('')
67
+ $stdout.should_receive(:print).with("Enter your default for private networking (optional, defaults to false): ")
68
+ $stdin.should_receive(:gets).and_return('')
65
69
 
66
70
  @cli.authorize
67
71
 
68
72
  expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
69
73
 
70
- File.read(tmp_path).should include "image: '284203'", "region: '1'", "size: '66'", "ssh_user: #{ENV['USER']}", "ssh_key_path: ~/.ssh/id_rsa", "ssh_port: '22'", "ssh_key: ''"
74
+ File.read(tmp_path).should include "image: '350076'", "region: '1'", "size: '66'", "ssh_user: #{ENV['USER']}", "ssh_key_path: ~/.ssh/id_rsa", "ssh_port: '22'", "ssh_key: ''"
71
75
 
72
76
  end
73
77
  end
@@ -5,7 +5,7 @@ describe Tugboat::CLI do
5
5
 
6
6
  describe "create a droplet" do
7
7
  it "with a name, uses defaults from configuration" do
8
- stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=#{image}&name=#{droplet_name}&region_id=#{region}&size_id=#{size}&ssh_key_ids=#{ssh_key_id}").
8
+ stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=#{image}&name=#{droplet_name}&private_networking=#{private_networking}&region_id=#{region}&size_id=#{size}&ssh_key_ids=#{ssh_key_id}").
9
9
  to_return(:status => 200, :body => '{"status":"OK"}')
10
10
 
11
11
  @cli.create(droplet_name)
@@ -13,11 +13,11 @@ describe Tugboat::CLI do
13
13
  expect($stdout.string).to eq <<-eos
14
14
  Queueing creation of droplet '#{droplet_name}'...done
15
15
  eos
16
- expect(a_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=#{image}&name=#{droplet_name}&region_id=#{region}&size_id=#{size}&ssh_key_ids=#{ssh_key_id}")).to have_been_made
16
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=#{image}&name=#{droplet_name}&private_networking=#{private_networking}&region_id=#{region}&size_id=#{size}&ssh_key_ids=#{ssh_key_id}")).to have_been_made
17
17
  end
18
18
 
19
19
  it "with args does not use defaults from configuration" do
20
- stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=555&name=foo&region_id=3&size_id=666&ssh_key_ids=4321").
20
+ stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=555&name=foo&private_networking=#{private_networking}&region_id=3&size_id=666&ssh_key_ids=4321").
21
21
  to_return(:status => 200, :body => '{"status":"OK"}')
22
22
 
23
23
  @cli.options = @cli.options.merge(:image => '555', :size => '666', :region => '3', :keys => '4321')
@@ -27,7 +27,7 @@ Queueing creation of droplet '#{droplet_name}'...done
27
27
  Queueing creation of droplet '#{droplet_name}'...done
28
28
  eos
29
29
 
30
- expect(a_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=555&name=foo&region_id=3&size_id=666&ssh_key_ids=4321")).to have_been_made
30
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=555&name=foo&private_networking=#{private_networking}&region_id=3&size_id=666&ssh_key_ids=4321")).to have_been_made
31
31
  end
32
32
  end
33
33
 
@@ -23,22 +23,22 @@ describe Tugboat::Configuration do
23
23
  end
24
24
 
25
25
  describe "the file" do
26
- let(:client_key) { "foo" }
27
- let(:api_key) { "bar" }
28
- let(:ssh_user) { "baz" }
29
- let(:ssh_key_path) { "~/.ssh/id_rsa2" }
30
- let(:ssh_key_path) { "~/.ssh/id_rsa2.pub" }
31
- let(:ssh_port) { "22" }
32
- let(:region) { "2" }
33
- let(:image) { "345791" }
34
- let(:size) { "66" }
35
- let(:ssh_key_id) { '1234' }
26
+ let(:client_key) { "foo" }
27
+ let(:api_key) { "bar" }
28
+ let(:ssh_user) { "baz" }
29
+ let(:ssh_key_path) { "~/.ssh/id_rsa2" }
30
+ let(:ssh_port) { "22" }
31
+ let(:region) { "2" }
32
+ let(:image) { "345791" }
33
+ let(:size) { "66" }
34
+ let(:ssh_key_id) { '1234' }
35
+ let(:private_networking) { 'true' }
36
36
 
37
37
  let(:config) { config = Tugboat::Configuration.instance }
38
38
 
39
39
  before :each do
40
40
  # Create a temporary file
41
- config.create_config_file(client_key, api_key, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key_id)
41
+ config.create_config_file(client_key, api_key, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key_id, private_networking)
42
42
  end
43
43
 
44
44
  it "can be created" do
@@ -85,20 +85,25 @@ describe Tugboat::Configuration do
85
85
  ssh = data["ssh"]
86
86
  expect(ssh).to have_key("ssh_port")
87
87
  end
88
+
89
+ it "should have private_networking set" do
90
+ private_networking = data["defaults"]
91
+ expect(private_networking).to have_key("private_networking")
92
+ end
88
93
  end
89
94
  describe "backwards compatible" do
90
95
  let(:client_key) { "foo" }
91
96
  let(:api_key) { "bar" }
92
97
  let(:ssh_user) { "baz" }
93
98
  let(:ssh_key_path) { "~/.ssh/id_rsa2" }
94
- let(:ssh_key_path) { "~/.ssh/id_rsa2.pub" }
95
99
  let(:ssh_port) { "22" }
96
100
 
97
- let(:config) { config = Tugboat::Configuration.instance }
98
- let(:config_default_region) { Tugboat::Configuration::DEFAULT_REGION }
99
- let(:config_default_image) { Tugboat::Configuration::DEFAULT_IMAGE }
100
- let(:config_default_size) { Tugboat::Configuration::DEFAULT_SIZE }
101
- let(:config_default_ssh_key) { Tugboat::Configuration::DEFAULT_SSH_KEY }
101
+ let(:config) { config = Tugboat::Configuration.instance }
102
+ let(:config_default_region) { Tugboat::Configuration::DEFAULT_REGION }
103
+ let(:config_default_image) { Tugboat::Configuration::DEFAULT_IMAGE }
104
+ let(:config_default_size) { Tugboat::Configuration::DEFAULT_SIZE }
105
+ let(:config_default_ssh_key) { Tugboat::Configuration::DEFAULT_SSH_KEY }
106
+ let(:config_default_networking) { Tugboat::Configuration::DEFAULT_PRIVATE_NETWORKING }
102
107
  let(:backwards_config) {
103
108
  {
104
109
  "authentication" => { "client_key" => client_key, "api_key" => api_key },
@@ -135,5 +140,10 @@ describe Tugboat::Configuration do
135
140
  expect(ssh_key).to eql config_default_ssh_key
136
141
  end
137
142
 
143
+ it "should use default private networking option if not in configuration" do
144
+ private_networking = config.default_private_networking
145
+ expect(private_networking).to eql config_default_networking
146
+ end
147
+
138
148
  end
139
149
  end
@@ -0,0 +1,8 @@
1
+ {
2
+ "status": "OK",
3
+ "ssh_key": {
4
+ "id": 47,
5
+ "name": "my_key",
6
+ "ssh_pub_key": "ssh-dss AAAAB3NzaC1kc3MAAACBAK5uLwicCrFEpaVKBzkWxC7RQn+smg5ZQb5keh9RQKo8AszFTol5npgUAr0JWmqKIHv7nof0HndO86x9iIqNjq3vrz9CIVcFfZM7poKBJZ27Hv3v0fmSKfAc6eGdx8eM9UkZe1gzcLXK8UP2HaeY1Y4LlaHXS5tPi/dXooFVgiA7AAAAFQCQl6LZo/VYB9VgPEZzOmsmQevnswAAAIBCNKGsVP5eZ+IJklXheUyzyuL75i04OOtEGW6MO5TymKMwTZlU9r4ukuwxty+T9Ot2LqlNRnLSPQUjb0vplasZ8Ix45JOpRbuSvPovryn7rvS7//klu9hIkFAAQ/AZfGTw+696EjFBg4F5tN6MGMA6KrTQVLXeuYcZeRXwE5t5lwAAAIEAl2xYh098bozJUANQ82DiZznjHc5FW76Xm1apEqsZtVRFuh3V9nc7QNcBekhmHp5Z0sHthXCm1XqnFbkRCdFlX02NpgtNs7OcKpaJP47N8C+C/Yrf8qK/Wt3fExrL2ZLX5XD2tiotugSkwZJMW5Bv0mtjrNt0Q7P45rZjNNTag2c= user@host"
7
+ }
8
+ }
@@ -35,10 +35,12 @@ describe Tugboat::Middleware::SSHDroplet do
35
35
  "-p", ssh_port,
36
36
  "-q",
37
37
  "-X",
38
- "#{ssh_user}@#{droplet_ip}")
38
+ "#{ssh_user}@#{droplet_ip}",
39
+ "echo hello")
39
40
 
40
41
  env["droplet_ip"] = droplet_ip
41
42
  env["config"] = config
43
+ env["user_droplet_ssh_command"] = "echo hello"
42
44
  env["user_droplet_ssh_opts"] = "-q -X"
43
45
 
44
46
  described_class.new(app).call(env)
@@ -2,22 +2,25 @@ require 'spec_helper'
2
2
 
3
3
  shared_context "spec" do
4
4
  # Default configuration and
5
- let(:config) { Tugboat::Configuration.instance }
6
- let(:client_key) { "foo" }
7
- let(:api_key) { "bar" }
8
- let(:ssh_user) { "baz" }
9
- let(:ssh_port) { "33" }
10
- let(:ssh_key_path) { "~/.ssh/id_rsa2" }
11
- let(:droplet_name) { "foo" }
12
- let(:droplet_ip) { "33.33.33.10" }
13
- let(:droplet_id) { 1234 }
14
- let(:region) { '3' }
15
- let(:image) { '345791'}
16
- let(:size) { '67'}
17
- let(:ssh_key_id) { '1234' }
18
- let(:ocean) { DigitalOcean::API.new :client_id => client_key, :api_key =>api_key }
19
- let(:app) { lambda { |env| } }
20
- let(:env) { {} }
5
+ let(:config) { Tugboat::Configuration.instance }
6
+ let(:client_key) { "foo" }
7
+ let(:api_key) { "bar" }
8
+ let(:ssh_user) { "baz" }
9
+ let(:ssh_port) { "33" }
10
+ let(:ssh_key_path) { "~/.ssh/id_rsa2" }
11
+ let(:droplet_name) { "foo" }
12
+ let(:droplet_ip) { "33.33.33.10" }
13
+ let(:droplet_id) { 1234 }
14
+ let(:region) { '3' }
15
+ let(:image) { '345791'}
16
+ let(:size) { '67'}
17
+ let(:ssh_key_id) { '1234' }
18
+ let(:ssh_key_name) { 'macbook_pro' }
19
+ let(:ssh_public_key) { 'ssh-dss A123= user@host' }
20
+ let(:private_networking) { 'false'}
21
+ let(:ocean) { DigitalOcean::API.new :client_id => client_key, :api_key =>api_key }
22
+ let(:app) { lambda { |env| } }
23
+ let(:env) { {} }
21
24
 
22
25
  before(:each) do
23
26
  $stdout.sync = true
@@ -26,7 +29,7 @@ shared_context "spec" do
26
29
  @cli = Tugboat::CLI.new
27
30
 
28
31
  # Set a temprary project path and create fake config.
29
- config.create_config_file(client_key, api_key, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key_id)
32
+ config.create_config_file(client_key, api_key, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key_id, private_networking)
30
33
  config.reload!
31
34
 
32
35
  # Keep track of the old stderr / out
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tugboat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Pearkes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-07 00:00:00.000000000 Z
11
+ date: 2013-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -157,6 +157,7 @@ files:
157
157
  - lib/tugboat/cli.rb
158
158
  - lib/tugboat/config.rb
159
159
  - lib/tugboat/middleware.rb
160
+ - lib/tugboat/middleware/add_key.rb
160
161
  - lib/tugboat/middleware/ask_for_credentials.rb
161
162
  - lib/tugboat/middleware/authentication_middleware.rb
162
163
  - lib/tugboat/middleware/base.rb
@@ -186,6 +187,7 @@ files:
186
187
  - lib/tugboat/middleware/start_droplet.rb
187
188
  - lib/tugboat/middleware/wait_for_state.rb
188
189
  - lib/tugboat/version.rb
190
+ - spec/cli/add_key_spec.rb
189
191
  - spec/cli/authorize_cli_spec.rb
190
192
  - spec/cli/create_cli_spec.rb
191
193
  - spec/cli/destroy_cli_spec.rb
@@ -208,6 +210,7 @@ files:
208
210
  - spec/cli/wait_cli_spec.rb
209
211
  - spec/config_spec.rb
210
212
  - spec/fixtures/create_droplet.json
213
+ - spec/fixtures/create_ssh_key.json
211
214
  - spec/fixtures/show_droplet.json
212
215
  - spec/fixtures/show_droplet_inactive.json
213
216
  - spec/fixtures/show_droplets.json
@@ -250,11 +253,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
253
  version: '0'
251
254
  requirements: []
252
255
  rubyforge_project:
253
- rubygems_version: 2.0.3
256
+ rubygems_version: 2.0.6
254
257
  signing_key:
255
258
  specification_version: 4
256
259
  summary: A command line tool for interacting with your DigitalOcean droplets.
257
260
  test_files:
261
+ - spec/cli/add_key_spec.rb
258
262
  - spec/cli/authorize_cli_spec.rb
259
263
  - spec/cli/create_cli_spec.rb
260
264
  - spec/cli/destroy_cli_spec.rb
@@ -277,6 +281,7 @@ test_files:
277
281
  - spec/cli/wait_cli_spec.rb
278
282
  - spec/config_spec.rb
279
283
  - spec/fixtures/create_droplet.json
284
+ - spec/fixtures/create_ssh_key.json
280
285
  - spec/fixtures/show_droplet.json
281
286
  - spec/fixtures/show_droplet_inactive.json
282
287
  - spec/fixtures/show_droplets.json
@@ -298,4 +303,3 @@ test_files:
298
303
  - spec/middleware/ssh_droplet_spec.rb
299
304
  - spec/shared/environment.rb
300
305
  - spec/spec_helper.rb
301
- has_rdoc: