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 +4 -4
- data/CHANGELOG.md +20 -1
- data/README.md +10 -1
- data/lib/tugboat.rb +1 -0
- data/lib/tugboat/cli.rb +29 -1
- data/lib/tugboat/config.rb +26 -6
- data/lib/tugboat/middleware.rb +26 -15
- data/lib/tugboat/middleware/add_key.rb +47 -0
- data/lib/tugboat/middleware/ask_for_credentials.rb +3 -2
- data/lib/tugboat/middleware/create_droplet.rb +10 -5
- data/lib/tugboat/middleware/ssh_droplet.rb +3 -0
- data/lib/tugboat/version.rb +1 -1
- data/spec/cli/add_key_spec.rb +72 -0
- data/spec/cli/authorize_cli_spec.rb +8 -4
- data/spec/cli/create_cli_spec.rb +4 -4
- data/spec/config_spec.rb +27 -17
- data/spec/fixtures/create_ssh_key.json +8 -0
- data/spec/middleware/ssh_droplet_spec.rb +3 -1
- data/spec/shared/environment.rb +20 -17
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d849915ab2227a3a3ffa08de72535a611cfbd84
|
4
|
+
data.tar.gz: 62a801c0f5e32a631d290e05528f2805813d7f58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0248ef0e63f0b8d62ab68027740fc5ba22b31f5c9c20d7df711d51f6f4e3a35aa69369bf6dbaa677b3e3b0f421865133ea0bdca13e84a530f0c5520393d4a547
|
7
|
+
data.tar.gz: c1afc811c11f657f3821b2407164a63616368546c67f88f3eb67d14138c3eaf1ea00244132d0aa409f882467bf3f01a096ab6d7410ef12cb2efec8f51eb3d778
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,23 @@
|
|
1
|
-
## 0.0.
|
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
|
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
|
|
data/lib/tugboat.rb
CHANGED
data/lib/tugboat/cli.rb
CHANGED
@@ -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({})
|
data/lib/tugboat/config.rb
CHANGED
@@ -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 = '
|
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" => {
|
115
|
-
|
116
|
-
|
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
|
data/lib/tugboat/middleware.rb
CHANGED
@@ -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 :
|
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 :
|
18
|
-
autoload :
|
19
|
-
autoload :
|
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 :
|
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
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
data/lib/tugboat/version.rb
CHANGED
@@ -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
|
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
|
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: '
|
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
|
data/spec/cli/create_cli_spec.rb
CHANGED
@@ -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}®ion_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}®ion_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}®ion_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}®ion_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®ion_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}®ion_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®ion_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}®ion_id=3&size_id=666&ssh_key_ids=4321")).to have_been_made
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
data/spec/config_spec.rb
CHANGED
@@ -23,22 +23,22 @@ describe Tugboat::Configuration do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
describe "the file" do
|
26
|
-
let(:client_key)
|
27
|
-
let(:api_key)
|
28
|
-
let(:ssh_user)
|
29
|
-
let(:ssh_key_path)
|
30
|
-
let(:
|
31
|
-
let(:
|
32
|
-
let(:
|
33
|
-
let(:
|
34
|
-
let(:
|
35
|
-
let(:
|
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)
|
98
|
-
let(:config_default_region)
|
99
|
-
let(:config_default_image)
|
100
|
-
let(:config_default_size)
|
101
|
-
let(:config_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)
|
data/spec/shared/environment.rb
CHANGED
@@ -2,22 +2,25 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
shared_context "spec" do
|
4
4
|
# Default configuration and
|
5
|
-
let(:config)
|
6
|
-
let(:client_key)
|
7
|
-
let(:api_key)
|
8
|
-
let(:ssh_user)
|
9
|
-
let(:ssh_port)
|
10
|
-
let(:ssh_key_path)
|
11
|
-
let(:droplet_name)
|
12
|
-
let(:droplet_ip)
|
13
|
-
let(:droplet_id)
|
14
|
-
let(:region)
|
15
|
-
let(:image)
|
16
|
-
let(:size)
|
17
|
-
let(:ssh_key_id)
|
18
|
-
let(:
|
19
|
-
let(:
|
20
|
-
let(:
|
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.
|
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-
|
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.
|
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:
|