tugboat 0.2.0 → 1.0.0

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.
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
+