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