tugboat 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -4
  4. data/CHANGELOG.md +325 -102
  5. data/CHANGELOG_old.md +150 -0
  6. data/Gemfile +6 -0
  7. data/README.md +12 -6
  8. data/Rakefile +7 -3
  9. data/features/step_definitions/steps.rb +0 -0
  10. data/features/support/env.rb +9 -0
  11. data/features/vagrant-adam/config_current_directory.feature +27 -0
  12. data/lib/tugboat/cli.rb +31 -3
  13. data/lib/tugboat/config.rb +13 -5
  14. data/lib/tugboat/middleware.rb +8 -0
  15. data/lib/tugboat/middleware/ask_for_credentials.rb +5 -4
  16. data/lib/tugboat/middleware/authentication_middleware.rb +2 -2
  17. data/lib/tugboat/middleware/config.rb +29 -0
  18. data/lib/tugboat/middleware/custom_logger.rb +2 -2
  19. data/lib/tugboat/middleware/find_droplet.rb +4 -0
  20. data/lib/tugboat/middleware/info_droplet.rb +5 -0
  21. data/lib/tugboat/middleware/inject_client.rb +1 -1
  22. data/lib/tugboat/middleware/list_droplets.rb +5 -1
  23. data/lib/tugboat/middleware/list_regions.rb +2 -2
  24. data/lib/tugboat/middleware/ssh_droplet.rb +17 -2
  25. data/lib/tugboat/version.rb +1 -1
  26. data/spec/cli/add_key_spec.rb +9 -9
  27. data/spec/cli/authorize_cli_spec.rb +76 -52
  28. data/spec/cli/create_cli_spec.rb +39 -4
  29. data/spec/cli/debug_cli_spec.rb +44 -0
  30. data/spec/cli/destroy_cli_spec.rb +30 -11
  31. data/spec/cli/destroy_image_cli_spec.rb +11 -11
  32. data/spec/cli/droplets_cli_spec.rb +6 -6
  33. data/spec/cli/halt_cli_spec.rb +9 -9
  34. data/spec/cli/images_cli_spec.rb +6 -6
  35. data/spec/cli/info_cli_spec.rb +42 -7
  36. data/spec/cli/info_image_cli_spec.rb +6 -6
  37. data/spec/cli/keys_cli_spec.rb +1 -1
  38. data/spec/cli/password_reset_cli_spec.rb +8 -8
  39. data/spec/cli/rebuild_cli_spec.rb +49 -49
  40. data/spec/cli/regions_cli_spec.rb +4 -4
  41. data/spec/cli/resize_cli_spec.rb +8 -8
  42. data/spec/cli/restart_cli_spec.rb +8 -8
  43. data/spec/cli/sizes_cli_spec.rb +1 -1
  44. data/spec/cli/snapshot_cli_spec.rb +7 -7
  45. data/spec/cli/ssh_cli_spec.rb +4 -4
  46. data/spec/cli/start_cli_spec.rb +7 -7
  47. data/spec/cli/verify_cli_spec.rb +10 -2
  48. data/spec/cli/wait_cli_spec.rb +6 -6
  49. data/spec/fixtures/500.html +68 -0
  50. data/spec/fixtures/show_droplet.json +1 -0
  51. data/spec/fixtures/show_droplet_fuzzy.json +13 -0
  52. data/spec/fixtures/show_droplet_inactive.json +1 -0
  53. data/spec/fixtures/show_droplets.json +2 -0
  54. data/spec/fixtures/show_droplets_fuzzy.json +35 -0
  55. data/spec/fixtures/show_droplets_inactive.json +2 -0
  56. data/spec/fixtures/show_regions.json +9 -6
  57. data/spec/middleware/base_spec.rb +1 -1
  58. data/spec/middleware/check_credentials_spec.rb +1 -1
  59. data/spec/middleware/inject_client_spec.rb +29 -0
  60. data/spec/middleware/inject_configuration_spec.rb +1 -1
  61. data/spec/middleware/ssh_droplet_spec.rb +30 -7
  62. data/spec/shared/environment.rb +1 -0
  63. data/spec/spec_helper.rb +11 -4
  64. data/tugboat.gemspec +9 -7
  65. metadata +64 -33
@@ -0,0 +1,29 @@
1
+ module Tugboat
2
+ module Middleware
3
+ # Check if the droplet in the environment is inactive, or "off"
4
+ class Config < Base
5
+ def call(env)
6
+
7
+ config = Tugboat::Configuration.instance
8
+
9
+ keys_retracted = ''
10
+
11
+ config_data = config.data.to_yaml
12
+
13
+ if env["user_hide_keys"]
14
+ keys_retracted = '(Keys Redacted)'
15
+ config_data = config_data.gsub(/(client_key: )([a-zA-Z0-9]+)/,'\1 [REDACTED]')
16
+ config_data = config_data.gsub(/(api_key: )([a-zA-Z0-9]+)/,'\1 [REDACTED]')
17
+ end
18
+
19
+ say "Current Config #{keys_retracted}", :green
20
+
21
+ say "Path: #{config.path}"
22
+ say config_data
23
+
24
+ @app.call(env)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -7,7 +7,7 @@ module Tugboat
7
7
  @app = app
8
8
  @logger = options.fetch(:logger) {
9
9
  require 'logger'
10
- ::Logger.new(STDOUT)
10
+ ::Logger.new($stdout)
11
11
  }
12
12
  end
13
13
 
@@ -26,7 +26,7 @@ module Tugboat
26
26
  private
27
27
 
28
28
  def filter(output)
29
- unless ENV['DEBUG'] == '2'
29
+ if ENV['DEBUG'].to_i == 2
30
30
  output = output.to_s.gsub(/client_id=[a-zA-Z0-9]*/,'client_id=[CLIENT-ID]')
31
31
  output = output.to_s.gsub(/api_key=[a-zA-Z0-9]*/,'api_key=[API-KEY]')
32
32
  output = output.to_s.gsub(/_digitalocean2_session_v2=[a-zA-Z0-9%-]*/,'_digitalocean2_session_v2=[SESSION_COOKIE]')
@@ -33,6 +33,7 @@ module Tugboat
33
33
  env["droplet_id"] = req.droplet.id
34
34
  env["droplet_name"] = "(#{req.droplet.name})"
35
35
  env["droplet_ip"] = req.droplet.ip_address
36
+ env["droplet_ip_private"] = req.droplet.private_ip_address
36
37
  env["droplet_status"] = req.droplet.status
37
38
  end
38
39
 
@@ -47,6 +48,7 @@ module Tugboat
47
48
  env["droplet_id"] = d.id
48
49
  env["droplet_name"] = "(#{d.name})"
49
50
  env["droplet_ip"] = d.ip_address
51
+ env["droplet_ip_private"] = d.private_ip_address
50
52
  env["droplet_status"] = d.status
51
53
  end
52
54
  end
@@ -83,6 +85,7 @@ module Tugboat
83
85
  env["droplet_id"] = found_droplets.first.id
84
86
  env["droplet_name"] = "(#{found_droplets.first.name})"
85
87
  env["droplet_ip"] = found_droplets.first.ip_address
88
+ env["droplet_ip_private"] = found_droplets.first.private_ip_address
86
89
  env["droplet_status"] = found_droplets.first.status
87
90
  elsif found_droplets.length > 1
88
91
  # Did we run the multiple questionairre?
@@ -99,6 +102,7 @@ module Tugboat
99
102
  env["droplet_id"] = found_droplets[choice.to_i].id
100
103
  env["droplet_name"] = found_droplets[choice.to_i].name
101
104
  env["droplet_ip"] = found_droplets[choice.to_i].ip_address
105
+ env["droplet_ip_private"] = found_droplets[choice.to_i].private_ip_address
102
106
  env["droplet_status"] = found_droplets[choice.to_i].status
103
107
  end
104
108
 
@@ -24,6 +24,11 @@ module Tugboat
24
24
  say "ID: #{droplet.id}"
25
25
  say "Status: #{status_color}#{droplet.status}#{CLEAR}"
26
26
  say "IP: #{droplet.ip_address}"
27
+
28
+ if droplet.private_ip_address
29
+ say "Private IP: #{droplet.private_ip_address}"
30
+ end
31
+
27
32
  say "Region ID: #{droplet.region_id}"
28
33
  say "Image ID: #{droplet.image_id}"
29
34
  say "Size ID: #{droplet.size_id}"
@@ -14,7 +14,7 @@ module Tugboat
14
14
  faraday.use CustomLogger if ENV['DEBUG']
15
15
  faraday.request :url_encoded
16
16
  faraday.response :rashify
17
- faraday.response :json
17
+ faraday.response :json, :content_type => /\b(json|json-home)$/
18
18
  faraday.adapter Faraday.default_adapter
19
19
  end
20
20
  end
@@ -13,13 +13,17 @@ module Tugboat
13
13
  else
14
14
  droplet_list.each do |droplet|
15
15
 
16
+ if droplet.private_ip_address
17
+ private_ip = ", privateip: #{droplet.private_ip_address}"
18
+ end
19
+
16
20
  if droplet.status == "active"
17
21
  status_color = GREEN
18
22
  else
19
23
  status_color = RED
20
24
  end
21
25
 
22
- say "#{droplet.name} (ip: #{droplet.ip_address}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region_id}, id: #{droplet.id})"
26
+ say "#{droplet.name} (ip: #{droplet.ip_address}#{private_ip}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region_id}, id: #{droplet.id})"
23
27
  end
24
28
  end
25
29
 
@@ -3,11 +3,11 @@ module Tugboat
3
3
  class ListRegions < Base
4
4
  def call(env)
5
5
  ocean = env["ocean"]
6
- regions = ocean.regions.list.regions
6
+ regions = ocean.regions.list.regions.sort_by(&:name)
7
7
 
8
8
  say "Regions:"
9
9
  regions.each do |region|
10
- say "#{region.name} (id: #{region.id})"
10
+ say "#{region.name} (id: #{region.id}) (slug: #{region.slug})"
11
11
  end
12
12
 
13
13
  @app.call(env)
@@ -9,7 +9,7 @@ module Tugboat
9
9
  "-o", "LogLevel=ERROR",
10
10
  "-o", "StrictHostKeyChecking=no",
11
11
  "-o", "UserKnownHostsFile=/dev/null",
12
- "-i", env["config"].ssh_key_path.to_s]
12
+ "-i", File.expand_path(env["config"].ssh_key_path.to_s)]
13
13
 
14
14
  if env["user_droplet_ssh_port"]
15
15
  options.push("-p", env["user_droplet_ssh_port"].to_s)
@@ -24,7 +24,22 @@ module Tugboat
24
24
  end
25
25
 
26
26
  ssh_user = env["user_droplet_ssh_user"] || env["config"].ssh_user
27
- host_string = "#{ssh_user}@#{env["droplet_ip"]}"
27
+
28
+ host_ip = env["droplet_ip"]
29
+
30
+ if env["droplet_ip_private"]
31
+ use_public_ip = env["config"].use_public_ip
32
+
33
+ if not env["user_droplet_use_public_ip"].nil?
34
+ use_public_ip = env["user_droplet_use_public_ip"]
35
+ end
36
+
37
+ if not use_public_ip
38
+ host_ip = env["droplet_ip_private"]
39
+ end
40
+ end
41
+
42
+ host_string = "#{ssh_user}@#{host_ip}"
28
43
 
29
44
  options << host_string
30
45
 
@@ -1,3 +1,3 @@
1
1
  module Tugboat
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -20,7 +20,7 @@ describe Tugboat::CLI do
20
20
  it "with a name and key string" do
21
21
 
22
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"))
23
+ to_return(:headers => {'Content-Type' => 'application/json'}, :status => 200, :body => fixture("create_ssh_key"))
24
24
 
25
25
  @cli.options = @cli.options.merge(:key => "#{ssh_public_key}")
26
26
  @cli.add_key(ssh_key_name)
@@ -33,21 +33,21 @@ Queueing upload of SSH key '#{ssh_key_name}'...done
33
33
  end
34
34
 
35
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)
36
+ allow(ENV).to receive(:[]).with('HOME').and_return(fake_home)
37
+ allow(ENV).to receive(:[]).with('DEBUG').and_return(nil)
38
+ allow(ENV).to receive(:[]).with('http_proxy').and_return(nil)
39
39
  FileUtils.mkdir_p "#{fake_home}/.ssh"
40
40
  File.open("#{fake_home}/.ssh/id_rsa.pub", 'w') {|f| f.write("ssh-dss A456= user@host") }
41
41
  end
42
42
 
43
43
  it "with name, prompts from file folder" do
44
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"))
45
+ to_return(:headers => {'Content-Type' => 'application/json'}, :status => 200, :body => fixture("create_ssh_key"))
46
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")
47
+ expect($stdout).to receive(:print).exactly(4).times
48
+ expect($stdout).to receive(:print).with("Enter the path to your SSH key: ")
49
+ expect($stdout).to receive(:print).with("Queueing upload of SSH key '#{ssh_key_name}'...")
50
+ expect($stdin).to receive(:gets).and_return("#{fake_home}/.ssh/id_rsa.pub")
51
51
 
52
52
  @cli.add_key(ssh_key_name)
53
53
 
@@ -8,77 +8,101 @@ describe Tugboat::CLI do
8
8
  describe "authorize" do
9
9
  before do
10
10
  stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
11
- to_return(:status => 200)
11
+ to_return(:headers => {'Content-Type' => 'application/json'}, :status => 200)
12
12
  end
13
13
 
14
14
  it "asks the right questions and checks credentials" do
15
15
 
16
- $stdout.should_receive(:print).exactly(6).times
17
- $stdout.should_receive(:print).with("Enter your client key: ")
18
- $stdin.should_receive(:gets).and_return(client_key)
19
- $stdout.should_receive(:print).with("Enter your API key: ")
20
- $stdin.should_receive(:gets).and_return(api_key)
21
- $stdout.should_receive(:print).with("Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa): ")
22
- $stdin.should_receive(:gets).and_return(ssh_key_path)
23
- $stdout.should_receive(:print).with("Enter your SSH user (optional, defaults to #{ENV['USER']}): ")
24
- $stdin.should_receive(:gets).and_return(ssh_user)
25
- $stdout.should_receive(:print).with("Enter your SSH port number (optional, defaults to 22): ")
26
- $stdin.should_receive(:gets).and_return(ssh_port)
27
- $stdout.should_receive(:print).with("Enter your default region ID (optional, defaults to 1 (New York)): ")
28
- $stdin.should_receive(:gets).and_return(region)
29
- $stdout.should_receive(:print).with("Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)): ")
30
- $stdin.should_receive(:gets).and_return(image)
31
- $stdout.should_receive(:print).with("Enter your default size ID (optional, defaults to 66 (512MB)): ")
32
- $stdin.should_receive(:gets).and_return(size)
33
- $stdout.should_receive(:print).with("Enter your default ssh key ID (optional, defaults to none): ")
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)
37
- $stdout.should_receive(:print).with("Enter your default for enabling backups (optional, defaults to false): ")
38
- $stdin.should_receive(:gets).and_return(backups_enabled)
39
-
16
+ expect($stdout).to receive(:print).exactly(6).times
17
+ expect($stdout).to receive(:print).with("Enter your client key: ")
18
+ expect($stdin).to receive(:gets).and_return(client_key)
19
+ expect($stdout).to receive(:print).with("Enter your API key: ")
20
+ expect($stdin).to receive(:gets).and_return(api_key)
21
+ expect($stdout).to receive(:print).with("Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa): ")
22
+ expect($stdin).to receive(:gets).and_return(ssh_key_path)
23
+ expect($stdout).to receive(:print).with("Enter your SSH user (optional, defaults to root): ")
24
+ expect($stdin).to receive(:gets).and_return(ssh_user)
25
+ expect($stdout).to receive(:print).with("Enter your SSH port number (optional, defaults to 22): ")
26
+ expect($stdin).to receive(:gets).and_return(ssh_port)
27
+ expect($stdout).to receive(:print).with("Enter your default region ID (optional, defaults to 8 (New York 3)): ")
28
+ expect($stdin).to receive(:gets).and_return(region)
29
+ expect($stdout).to receive(:print).with("Enter your default image ID (optional, defaults to 9801950 (Ubuntu 14.04 x64)): ")
30
+ expect($stdin).to receive(:gets).and_return(image)
31
+ expect($stdout).to receive(:print).with("Enter your default size ID (optional, defaults to 66 (512MB)): ")
32
+ expect($stdin).to receive(:gets).and_return(size)
33
+ expect($stdout).to receive(:print).with("Enter your default ssh key ID (optional, defaults to none): ")
34
+ expect($stdin).to receive(:gets).and_return(ssh_key_id)
35
+ expect($stdout).to receive(:print).with("Enter your default for private networking (optional, defaults to false): ")
36
+ expect($stdin).to receive(:gets).and_return(private_networking)
37
+ expect($stdout).to receive(:print).with("Enter your default for enabling backups (optional, defaults to false): ")
38
+ expect($stdin).to receive(:gets).and_return(backups_enabled)
40
39
 
41
40
  @cli.authorize
42
41
 
43
- expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
42
+ expect($stdout.string).to include("Note: You can get this information from https://cloud.digitalocean.com/api_access")
43
+ expect($stdout.string).to include("Also Note: Tugboat is setup to work with v1 of the Digital Ocean API (https://developers.digitalocean.com/v1/)")
44
+ expect($stdout.string).to include("To retrieve region, image, size and key ID's, you can use the corresponding tugboat command, such as `tugboat images`.")
45
+ expect($stdout.string).to include("Defaults can be changed at any time in your ~/.tugboat configuration file.")
44
46
 
45
- 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}'", "backups_enabled: '#{backups_enabled}'"
47
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
46
48
 
49
+ config = YAML.load_file(tmp_path)
50
+
51
+ expect(config["defaults"]["image"]).to eq image
52
+ expect(config["defaults"]["region"]).to eq region
53
+ expect(config["defaults"]["size"]).to eq size
54
+ expect(config["ssh"]["ssh_user"]).to eq ssh_user
55
+ expect(config["ssh"]["ssh_key_path"]).to eq ssh_key_path
56
+ expect(config["ssh"]["ssh_port"]).to eq ssh_port
57
+ expect(config["defaults"]["ssh_key"]).to eq ssh_key_id
58
+ expect(config["defaults"]["private_networking"]).to eq private_networking
59
+ expect(config["defaults"]["backups_enabled"]).to eq backups_enabled
47
60
  end
48
61
 
49
62
  it "sets defaults if no input given" do
50
63
 
51
- $stdout.should_receive(:print).exactly(6).times
52
- $stdout.should_receive(:print).with("Enter your client key: ")
53
- $stdin.should_receive(:gets).and_return(client_key)
54
- $stdout.should_receive(:print).with("Enter your API key: ")
55
- $stdin.should_receive(:gets).and_return(api_key)
56
- $stdout.should_receive(:print).with("Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa): ")
57
- $stdin.should_receive(:gets).and_return(ssh_key_path)
58
- $stdout.should_receive(:print).with("Enter your SSH user (optional, defaults to #{ENV['USER']}): ")
59
- $stdin.should_receive(:gets).and_return('')
60
- $stdout.should_receive(:print).with("Enter your SSH port number (optional, defaults to 22): ")
61
- $stdin.should_receive(:gets).and_return('')
62
- $stdout.should_receive(:print).with("Enter your default region ID (optional, defaults to 1 (New York)): ")
63
- $stdin.should_receive(:gets).and_return('')
64
- $stdout.should_receive(:print).with("Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)): ")
65
- $stdin.should_receive(:gets).and_return('')
66
- $stdout.should_receive(:print).with("Enter your default size ID (optional, defaults to 66 (512MB)): ")
67
- $stdin.should_receive(:gets).and_return('')
68
- $stdout.should_receive(:print).with("Enter your default ssh key ID (optional, defaults to none): ")
69
- $stdin.should_receive(:gets).and_return('')
70
- $stdout.should_receive(:print).with("Enter your default for private networking (optional, defaults to false): ")
71
- $stdin.should_receive(:gets).and_return('')
72
- $stdout.should_receive(:print).with("Enter your default for enabling backups (optional, defaults to false): ")
73
- $stdin.should_receive(:gets).and_return('')
74
-
64
+ expect($stdout).to receive(:print).exactly(6).times
65
+ expect($stdout).to receive(:print).with("Enter your client key: ")
66
+ expect($stdin).to receive(:gets).and_return(client_key)
67
+ expect($stdout).to receive(:print).with("Enter your API key: ")
68
+ expect($stdin).to receive(:gets).and_return(api_key)
69
+ expect($stdout).to receive(:print).with("Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa): ")
70
+ expect($stdin).to receive(:gets).and_return(ssh_key_path)
71
+ expect($stdout).to receive(:print).with("Enter your SSH user (optional, defaults to root): ")
72
+ expect($stdin).to receive(:gets).and_return('')
73
+ expect($stdout).to receive(:print).with("Enter your SSH port number (optional, defaults to 22): ")
74
+ expect($stdin).to receive(:gets).and_return('')
75
+ expect($stdout).to receive(:print).with("Enter your default region ID (optional, defaults to 8 (New York 3)): ")
76
+ expect($stdin).to receive(:gets).and_return('')
77
+ expect($stdout).to receive(:print).with("Enter your default image ID (optional, defaults to 9801950 (Ubuntu 14.04 x64)): ")
78
+ expect($stdin).to receive(:gets).and_return('')
79
+ expect($stdout).to receive(:print).with("Enter your default size ID (optional, defaults to 66 (512MB)): ")
80
+ expect($stdin).to receive(:gets).and_return('')
81
+ expect($stdout).to receive(:print).with("Enter your default ssh key ID (optional, defaults to none): ")
82
+ expect($stdin).to receive(:gets).and_return('')
83
+ expect($stdout).to receive(:print).with("Enter your default for private networking (optional, defaults to false): ")
84
+ expect($stdin).to receive(:gets).and_return('')
85
+ expect($stdout).to receive(:print).with("Enter your default for enabling backups (optional, defaults to false): ")
86
+ expect($stdin).to receive(:gets).and_return('')
75
87
 
76
88
  @cli.authorize
77
89
 
90
+ expect($stdout.string).to include("Note: You can get this information from https://cloud.digitalocean.com/api_access")
91
+ expect($stdout.string).to include("Also Note: Tugboat is setup to work with v1 of the Digital Ocean API (https://developers.digitalocean.com/v1/)")
92
+ expect($stdout.string).to include("To retrieve region, image, size and key ID's, you can use the corresponding tugboat command, such as `tugboat images`.")
93
+ expect($stdout.string).to include("Defaults can be changed at any time in your ~/.tugboat configuration file.")
94
+
78
95
  expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
79
96
 
80
- 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: ''"
97
+ config = YAML.load_file(tmp_path)
81
98
 
99
+ expect(config["defaults"]["image"]).to eq "9801950"
100
+ expect(config["defaults"]["region"]).to eq "8"
101
+ expect(config["defaults"]["size"]).to eq "66"
102
+ expect(config["ssh"]["ssh_user"]).to eq 'root'
103
+ expect(config["ssh"]["ssh_key_path"]).to eq "~/.ssh/id_rsa2"
104
+ expect(config["ssh"]["ssh_port"]).to eq "22"
105
+ expect(config["defaults"]["ssh_key"]).to eq ""
82
106
  end
83
107
  end
84
108
 
@@ -6,7 +6,7 @@ describe Tugboat::CLI do
6
6
  describe "create a droplet" do
7
7
  it "with a name, uses defaults from configuration" do
8
8
  stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=#{image}&name=#{droplet_name}&backups_enabled=#{backups_enabled}&private_networking=#{private_networking}&region_id=#{region}&size_id=#{size}&ssh_key_ids=#{ssh_key_id}").
9
- to_return(:status => 200, :body => '{"status":"OK"}')
9
+ to_return(:headers => {'Content-Type' => 'application/json'}, :status => 200, :body => '{"status":"OK"}')
10
10
 
11
11
  @cli.create(droplet_name)
12
12
 
@@ -18,7 +18,7 @@ Queueing creation of droplet '#{droplet_name}'...done
18
18
 
19
19
  it "with args does not use defaults from configuration" do
20
20
  stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=555&name=foo&backups_enabled=#{backups_enabled}&private_networking=#{private_networking}&region_id=3&size_id=666&ssh_key_ids=4321").
21
- to_return(:status => 200, :body => '{"status":"OK"}')
21
+ to_return(:headers => {'Content-Type' => 'application/json'}, :status => 200, :body => '{"status":"OK"}')
22
22
 
23
23
  @cli.options = @cli.options.merge(:image => '555', :size => '666', :region => '3', :keys => '4321')
24
24
  @cli.create(droplet_name)
@@ -29,8 +29,43 @@ Queueing creation of droplet '#{droplet_name}'...done
29
29
 
30
30
  expect(a_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=555&name=foo&backups_enabled=#{backups_enabled}&private_networking=#{private_networking}&region_id=3&size_id=666&ssh_key_ids=4321")).to have_been_made
31
31
  end
32
- end
33
32
 
33
+ it "doesn't create a droplet when mistyping help command" do
34
+ help_text = <<-eos
35
+ Usage:
36
+ rspec create NAME
34
37
 
35
- end
38
+ Options:
39
+ -s, [--size=N] # The size_id of the droplet
40
+ -i, [--image=N] # The image_id of the droplet
41
+ -r, [--region=N] # The region_id of the droplet
42
+ -k, [--keys=KEYS] # A comma separated list of SSH key ids to add to the droplet
43
+ -p, [--private-networking] # Enable private networking on the droplet
44
+ -b, [--backups-enabled] # Enable backups on the droplet
45
+ -q, [--quiet]
46
+
47
+ Create a droplet.
48
+ eos
49
+
50
+ @cli.create('help')
51
+ expect($stdout.string).to eq help_text
52
+
53
+ @cli.create('--help')
54
+ expect($stdout.string).to eq help_text + help_text
55
+
56
+ @cli.create('-h')
57
+ expect($stdout.string).to eq help_text + help_text + help_text
58
+ end
36
59
 
60
+ it "does not clobber named droplets that contain the word help" do
61
+ stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=#{image}&name=somethingblahblah--help&backups_enabled=#{backups_enabled}&private_networking=#{private_networking}&region_id=#{region}&size_id=#{size}&ssh_key_ids=#{ssh_key_id}").
62
+ to_return(:headers => {'Content-Type' => 'application/json'}, :status => 200, :body => '{"status":"OK"}')
63
+
64
+ @cli.create('somethingblahblah--help')
65
+
66
+ expect($stdout.string).to eq <<-eos
67
+ Queueing creation of droplet 'somethingblahblah--help'...done
68
+ eos
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ describe "DEBUG=1" do
7
+ before(:each) do
8
+ allow(ENV).to receive(:[]).with('HOME').and_return('/tmp/fake_home')
9
+ allow(ENV).to receive(:[]).with('DEBUG').and_return(1)
10
+ allow(ENV).to receive(:[]).with('http_proxy').and_return(nil)
11
+ end
12
+
13
+ it "gives full faraday logs" do
14
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
15
+ to_return(:headers => {'Content-Type' => 'application/json'}, :status => 200, :body => fixture("show_droplets"))
16
+
17
+ @cli.droplets
18
+
19
+ expect($stdout.string).to include('Response from https://api.digitalocean.com/droplets?client_id=foo&api_key=bar; Status: 200;')
20
+
21
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
22
+ end
23
+ end
24
+
25
+ describe "DEBUG=2" do
26
+ before(:each) do
27
+ allow(ENV).to receive(:[]).with('HOME').and_return('/tmp/fake_home')
28
+ allow(ENV).to receive(:[]).with('DEBUG').and_return(2)
29
+ allow(ENV).to receive(:[]).with('http_proxy').and_return(nil)
30
+ end
31
+
32
+ it "gives full faraday logs with redacted API keys" do
33
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
34
+ to_return(:headers => {'Content-Type' => 'application/json'}, :status => 200, :body => fixture("show_droplets"))
35
+
36
+ @cli.droplets
37
+
38
+ expect($stdout.string).to include('Response from https://api.digitalocean.com/droplets?client_id=[CLIENT-ID]&api_key=[API-KEY]; Status: 200;')
39
+
40
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
41
+ end
42
+ end
43
+ end
44
+