tugboat 3.1.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -1
- data/CODE_OF_CONDUCT.md +46 -0
- data/lib/tugboat/cli.rb +7 -1
- data/lib/tugboat/config.rb +11 -1
- data/lib/tugboat/middleware.rb +2 -0
- data/lib/tugboat/middleware/ask_for_credentials.rb +2 -1
- data/lib/tugboat/middleware/base.rb +31 -13
- data/lib/tugboat/middleware/check_snapshot_parameters.rb +16 -0
- data/lib/tugboat/middleware/info_droplet.rb +2 -2
- data/lib/tugboat/middleware/inject_client.rb +10 -1
- data/lib/tugboat/middleware/list_droplets.rb +5 -3
- data/lib/tugboat/version.rb +1 -1
- data/spec/cli/add_key_spec.rb +7 -9
- data/spec/cli/authorize_cli_spec.rb +4 -34
- data/spec/cli/config_cli_spec.rb +10 -5
- data/spec/cli/create_cli_spec.rb +20 -17
- data/spec/cli/debug_cli_spec.rb +11 -12
- data/spec/cli/destroy_cli_spec.rb +35 -12
- data/spec/cli/destroy_image_cli_spec.rb +12 -10
- data/spec/cli/droplets_cli_spec.rb +74 -48
- data/spec/cli/env_variable_spec.rb +4 -4
- data/spec/cli/halt_cli_spec.rb +16 -13
- data/spec/cli/help_cli_spec.rb +4 -4
- data/spec/cli/images_cli_spec.rb +9 -7
- data/spec/cli/info_cli_spec.rb +120 -50
- data/spec/cli/info_image_cli_spec.rb +24 -23
- data/spec/cli/keys_cli_spec.rb +3 -3
- data/spec/cli/password_reset_cli_spec.rb +12 -12
- data/spec/cli/rebuild_cli_spec.rb +31 -24
- data/spec/cli/regions_cli_spec.rb +3 -3
- data/spec/cli/resize_cli_spec.rb +16 -16
- data/spec/cli/restart_cli_spec.rb +32 -11
- data/spec/cli/sizes_cli_spec.rb +3 -3
- data/spec/cli/snapshot_cli_spec.rb +25 -9
- data/spec/cli/ssh_cli_spec.rb +10 -10
- data/spec/cli/start_cli_spec.rb +15 -15
- data/spec/cli/verify_cli_spec.rb +4 -7
- data/spec/cli/version_cli_spec.rb +1 -2
- data/spec/cli/wait_cli_spec.rb +16 -16
- data/spec/config_spec.rb +7 -1
- data/spec/fixtures/show_droplets.json +7 -4
- data/spec/fixtures/show_droplets_paginated_first.json +10 -7
- data/spec/fixtures/show_droplets_paginated_last.json +11 -5
- data/spec/fixtures/show_droplets_private_ip.json +7 -4
- data/spec/middleware/base_spec.rb +1 -2
- data/spec/middleware/check_configuration_spec.rb +1 -1
- data/spec/middleware/check_credentials_spec.rb +1 -1
- data/spec/middleware/check_droplet_active_spec.rb +1 -1
- data/spec/middleware/check_droplet_inactive_spec.rb +1 -1
- data/spec/middleware/find_droplet_spec.rb +3 -5
- data/spec/middleware/find_image_spec.rb +3 -5
- data/spec/middleware/ssh_droplet_spec.rb +5 -10
- data/spec/shared/environment.rb +2 -18
- data/tugboat.gemspec +1 -2
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbcf98dca8237e5bfd743b99bff3f3a328adef69
|
4
|
+
data.tar.gz: 8a9d169c00582cc9c71de34f38573d35cfe1fee5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cce0f1c41b15927f149aa687b5f9e2f3edf05e50da812f54cac4ba69253f64a92bc792f9a77d79e8a09103e4c804f20172c121bc1da5337465b82ff1304a9aa
|
7
|
+
data.tar.gz: e0dc3a1f73e12a0da367269228fbcb79edcd58c995f1186e642f7be8283cf0a11a0924308e3ef05337deb471a131942ec5c1d30bcedf23bd91df3344891398c7
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,27 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [v4.0.0](https://github.com/petems/tugboat/tree/v4.0.0) (2017-12-03)
|
6
|
+
[Full Changelog](https://github.com/petems/tugboat/compare/v3.1.0...v4.0.0)
|
7
|
+
|
8
|
+
**Fixed bugs:**
|
9
|
+
|
10
|
+
- snapshot not working [\#280](https://github.com/petems/tugboat/issues/280)
|
11
|
+
- Release Tugboat for 2.4.1 support [\#279](https://github.com/petems/tugboat/issues/279)
|
12
|
+
- Timeout while executing tugboat wait [\#71](https://github.com/petems/tugboat/issues/71)
|
13
|
+
|
14
|
+
**Merged pull requests:**
|
15
|
+
|
16
|
+
- Removing `Assigned but unused variable` warnings [\#292](https://github.com/petems/tugboat/pull/292) ([petems](https://github.com/petems))
|
17
|
+
- Adds helper for showing snapshot parameter [\#290](https://github.com/petems/tugboat/pull/290) ([petems](https://github.com/petems))
|
18
|
+
- Updates Faraday middleware gem [\#289](https://github.com/petems/tugboat/pull/289) ([petems](https://github.com/petems))
|
19
|
+
- Create CODE\_OF\_CONDUCT.md [\#288](https://github.com/petems/tugboat/pull/288) ([petems](https://github.com/petems))
|
20
|
+
- Add Size Slug [\#287](https://github.com/petems/tugboat/pull/287) ([petems](https://github.com/petems))
|
21
|
+
- Changes debug output to allow multiple regex [\#286](https://github.com/petems/tugboat/pull/286) ([petems](https://github.com/petems))
|
22
|
+
- Switches `$stdout` redirection to rspec method [\#285](https://github.com/petems/tugboat/pull/285) ([petems](https://github.com/petems))
|
23
|
+
- Change listing droplets to use DK [\#284](https://github.com/petems/tugboat/pull/284) ([petems](https://github.com/petems))
|
24
|
+
- Add configurable timeout to config file [\#283](https://github.com/petems/tugboat/pull/283) ([petems](https://github.com/petems))
|
25
|
+
|
5
26
|
## [v3.1.0](https://github.com/petems/tugboat/tree/v3.1.0) (2017-07-13)
|
6
27
|
[Full Changelog](https://github.com/petems/tugboat/compare/v3.0.0...v3.1.0)
|
7
28
|
|
@@ -334,7 +355,7 @@ All notable changes to this project will be documented in this file.
|
|
334
355
|
|
335
356
|
- destroy and info command [\#91](https://github.com/petems/tugboat/pull/91) ([PierreFrisch](https://github.com/PierreFrisch))
|
336
357
|
- Add rebuild command [\#90](https://github.com/petems/tugboat/pull/90) ([PierreFrisch](https://github.com/PierreFrisch))
|
337
|
-
- Fuzzy name searching is now case insensitive [\#88](https://github.com/petems/tugboat/pull/88) ([
|
358
|
+
- Fuzzy name searching is now case insensitive [\#88](https://github.com/petems/tugboat/pull/88) ([dalemyers](https://github.com/dalemyers))
|
338
359
|
- global: add a -q/--quiet flag [\#87](https://github.com/petems/tugboat/pull/87) ([pearkes](https://github.com/pearkes))
|
339
360
|
- Add backups\_enabled option on droplet creation \(-b true\) [\#82](https://github.com/petems/tugboat/pull/82) ([4n3w](https://github.com/4n3w))
|
340
361
|
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
6
|
+
|
7
|
+
## Our Standards
|
8
|
+
|
9
|
+
Examples of behavior that contributes to creating a positive environment include:
|
10
|
+
|
11
|
+
* Using welcoming and inclusive language
|
12
|
+
* Being respectful of differing viewpoints and experiences
|
13
|
+
* Gracefully accepting constructive criticism
|
14
|
+
* Focusing on what is best for the community
|
15
|
+
* Showing empathy towards other community members
|
16
|
+
|
17
|
+
Examples of unacceptable behavior by participants include:
|
18
|
+
|
19
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
20
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
21
|
+
* Public or private harassment
|
22
|
+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
23
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
24
|
+
|
25
|
+
## Our Responsibilities
|
26
|
+
|
27
|
+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
28
|
+
|
29
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
30
|
+
|
31
|
+
## Scope
|
32
|
+
|
33
|
+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
34
|
+
|
35
|
+
## Enforcement
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at webmaster@petersouter.co.uk. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
38
|
+
|
39
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
40
|
+
|
41
|
+
## Attribution
|
42
|
+
|
43
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
44
|
+
|
45
|
+
[homepage]: http://contributor-covenant.org
|
46
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/lib/tugboat/cli.rb
CHANGED
@@ -66,11 +66,17 @@ module Tugboat
|
|
66
66
|
default: false,
|
67
67
|
aliases: '-i',
|
68
68
|
desc: 'Include URLs for the droplets (can be opened in a browser)'
|
69
|
+
method_option 'per_page',
|
70
|
+
type: :boolean,
|
71
|
+
default: 20,
|
72
|
+
aliases: '-p',
|
73
|
+
desc: 'Chose how many results to fetch from the DigitalOcean API (larger is slower)'
|
69
74
|
desc 'droplets [OPTIONS]', 'Retrieve a list of your droplets'
|
70
75
|
def droplets
|
71
76
|
Middleware.sequence_list_droplets.call('tugboat_action' => __method__,
|
72
77
|
'user_quiet' => options[:quiet],
|
73
|
-
'include_urls' => options['include_urls']
|
78
|
+
'include_urls' => options['include_urls'],
|
79
|
+
'per_page' => options['per_page'],)
|
74
80
|
end
|
75
81
|
|
76
82
|
desc 'images [OPTIONS]', 'Retrieve a list of images'
|
data/lib/tugboat/config.rb
CHANGED
@@ -20,6 +20,7 @@ module Tugboat
|
|
20
20
|
DEFAULT_PRIVATE_NETWORKING = 'false'.freeze
|
21
21
|
DEFAULT_BACKUPS_ENABLED = 'false'.freeze
|
22
22
|
DEFAULT_USER_DATA = nil
|
23
|
+
DEFAULT_TIMEOUT = 10
|
23
24
|
|
24
25
|
# Load config file from current directory, if not exit load from user's home directory
|
25
26
|
def initialize
|
@@ -95,6 +96,10 @@ module Tugboat
|
|
95
96
|
ENV['DO_API_TOKEN'] unless ENV['DO_API_TOKEN'].to_s.empty?
|
96
97
|
end
|
97
98
|
|
99
|
+
def timeout
|
100
|
+
@data['connection'].nil? || @data['connection']['timeout'].nil? ? DEFAULT_TIMEOUT : @data['connection']['timeout']
|
101
|
+
end
|
102
|
+
|
98
103
|
# Re-runs initialize
|
99
104
|
def reset!
|
100
105
|
send(:initialize)
|
@@ -106,7 +111,7 @@ module Tugboat
|
|
106
111
|
end
|
107
112
|
|
108
113
|
# Writes a config file
|
109
|
-
def create_config_file(access_token, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key, private_networking, backups_enabled, ip6)
|
114
|
+
def create_config_file(access_token, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key, private_networking, backups_enabled, ip6, timeout)
|
110
115
|
# Default SSH Key path
|
111
116
|
ssh_key_path = File.join('~', DEFAULT_SSH_KEY_PATH) if ssh_key_path.empty?
|
112
117
|
|
@@ -130,12 +135,17 @@ module Tugboat
|
|
130
135
|
|
131
136
|
ip6 = DEFAULT_IP6 if ip6.empty?
|
132
137
|
|
138
|
+
timeout = DEFAULT_TIMEOUT if timeout.empty?
|
139
|
+
|
133
140
|
require 'yaml'
|
134
141
|
File.open(@path, File::RDWR | File::TRUNC | File::CREAT, 0o600) do |file|
|
135
142
|
data = {
|
136
143
|
'authentication' => {
|
137
144
|
'access_token' => access_token
|
138
145
|
},
|
146
|
+
'connection' => {
|
147
|
+
'timeout' => timeout
|
148
|
+
},
|
139
149
|
'ssh' => {
|
140
150
|
'ssh_user' => ssh_user,
|
141
151
|
'ssh_key_path' => ssh_key_path,
|
data/lib/tugboat/middleware.rb
CHANGED
@@ -9,6 +9,7 @@ module Tugboat
|
|
9
9
|
autoload :CheckCredentials, 'tugboat/middleware/check_credentials'
|
10
10
|
autoload :CheckDropletActive, 'tugboat/middleware/check_droplet_active'
|
11
11
|
autoload :CheckDropletInactive, 'tugboat/middleware/check_droplet_inactive'
|
12
|
+
autoload :CheckSnapshotParameters, 'tugboat/middleware/check_snapshot_parameters'
|
12
13
|
autoload :Config, 'tugboat/middleware/config'
|
13
14
|
autoload :ConfirmAction, 'tugboat/middleware/confirm_action'
|
14
15
|
autoload :CreateDroplet, 'tugboat/middleware/create_droplet'
|
@@ -197,6 +198,7 @@ module Tugboat
|
|
197
198
|
# Snapshot a droplet
|
198
199
|
def self.sequence_snapshot_droplet
|
199
200
|
::Middleware::Builder.new do
|
201
|
+
use CheckSnapshotParameters
|
200
202
|
use InjectConfiguration
|
201
203
|
use CheckConfiguration
|
202
204
|
use InjectClient
|
@@ -6,6 +6,7 @@ module Tugboat
|
|
6
6
|
say 'Note: You can get your Access Token from https://cloud.digitalocean.com/settings/tokens/new', :yellow
|
7
7
|
say
|
8
8
|
access_token = ask 'Enter your access token:'
|
9
|
+
timeout = ask 'Enter your default timeout for connections in seconds (optional, defaults to 10):'
|
9
10
|
access_token.strip!
|
10
11
|
ssh_key_path = ask 'Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa):'
|
11
12
|
ssh_user = ask 'Enter your SSH user (optional, defaults to root):'
|
@@ -23,7 +24,7 @@ module Tugboat
|
|
23
24
|
ip6 = ask 'Enter your default for IPv6 (optional, defaults to false):'
|
24
25
|
|
25
26
|
# Write the config file.
|
26
|
-
env['config'].create_config_file(access_token, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key, private_networking, backups_enabled, ip6)
|
27
|
+
env['config'].create_config_file(access_token, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key, private_networking, backups_enabled, ip6, timeout)
|
27
28
|
env['config'].reload!
|
28
29
|
|
29
30
|
@app.call(env)
|
@@ -31,18 +31,29 @@ module Tugboat
|
|
31
31
|
|
32
32
|
def verify_credentials(ocean, say_success = false)
|
33
33
|
begin
|
34
|
-
|
34
|
+
if ocean.is_a?(DropletKit::Client)
|
35
|
+
response = ocean.droplets.all(per_page: '1', page: '1')
|
36
|
+
|
37
|
+
begin
|
38
|
+
response.first
|
39
|
+
rescue DropletKit::Error => e
|
40
|
+
say "Failed to connect to DigitalOcean. Reason given from API:\n#{e}", :red
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
else
|
44
|
+
response = ocean.droplet.all(per_page: '1', page: '1')
|
45
|
+
|
46
|
+
unless response.success?
|
47
|
+
say "Failed to connect to DigitalOcean. Reason given from API: #{response.id} - #{response.message}", :red
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
end
|
35
51
|
rescue Faraday::ClientError => e
|
36
52
|
say 'Authentication with DigitalOcean failed at an early stage'
|
37
53
|
say "Error was: #{e}"
|
38
54
|
exit 1
|
39
55
|
end
|
40
56
|
|
41
|
-
unless response.success?
|
42
|
-
say "Failed to connect to DigitalOcean. Reason given from API: #{response.id} - #{response.message}", :red
|
43
|
-
exit 1
|
44
|
-
end
|
45
|
-
|
46
57
|
say 'Authentication with DigitalOcean was successful.', :green if say_success
|
47
58
|
end
|
48
59
|
|
@@ -80,19 +91,26 @@ module Tugboat
|
|
80
91
|
end
|
81
92
|
|
82
93
|
# Get all pages of droplets
|
83
|
-
def get_droplet_list(ocean)
|
94
|
+
def get_droplet_list(ocean, per_page = 20)
|
84
95
|
verify_credentials(ocean)
|
85
96
|
|
86
|
-
|
87
|
-
|
97
|
+
# Allow both Barge and DropletKit usage
|
98
|
+
if ocean.is_a?(DropletKit::Client)
|
99
|
+
# DropletKit self-paginates
|
100
|
+
ocean.droplets.all(per_page: per_page)
|
101
|
+
else
|
102
|
+
page = ocean.droplet.all(per_page: 200, page: 1)
|
103
|
+
return page.droplets unless page.paginated?
|
88
104
|
|
89
|
-
|
90
|
-
page.droplets.each { |drop| enum.yield drop }
|
91
|
-
for page_num in 2..page.last_page
|
92
|
-
page = ocean.droplet.all(per_page: 200, page: page_num)
|
105
|
+
Enumerator.new do |enum|
|
93
106
|
page.droplets.each { |drop| enum.yield drop }
|
107
|
+
for page_num in 2..page.last_page
|
108
|
+
page = ocean.droplet.all(per_page: 200, page: page_num)
|
109
|
+
page.droplets.each { |drop| enum.yield drop }
|
110
|
+
end
|
94
111
|
end
|
95
112
|
end
|
113
|
+
|
96
114
|
end
|
97
115
|
end
|
98
116
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Tugboat
|
2
|
+
module Middleware
|
3
|
+
# Check if the droplet in the environment is active
|
4
|
+
class CheckSnapshotParameters < Base
|
5
|
+
def call(env)
|
6
|
+
unless env['user_droplet_id'] || env['user_droplet_name'] || env['user_droplet_fuzzy_name']
|
7
|
+
say 'You must provide a snapshot name followed by the droplet\'s name.', :red
|
8
|
+
say "For example: `tugboat snapshot #{env['user_snapshot_name']} example-node.com`", :green
|
9
|
+
exit 1
|
10
|
+
end
|
11
|
+
|
12
|
+
@app.call(env)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -23,7 +23,7 @@ module Tugboat
|
|
23
23
|
|
24
24
|
attribute = env['user_attribute']
|
25
25
|
|
26
|
-
droplet_ip4_public = droplet.networks.v4.find { |address| address.type == 'public' }.ip_address
|
26
|
+
droplet_ip4_public = droplet.networks.v4.find { |address| address.type == 'public' }.ip_address unless droplet.networks.v4.empty?
|
27
27
|
droplet_ip6_public = droplet.networks.v6.find { |address| address.type == 'public' }.ip_address unless droplet.networks.v6.empty?
|
28
28
|
check_private_ip = droplet.networks.v4.find { |address| address.type == 'private' }
|
29
29
|
droplet_private_ip = check_private_ip.ip_address if check_private_ip
|
@@ -59,7 +59,7 @@ module Tugboat
|
|
59
59
|
say "Name: #{droplet.name}"
|
60
60
|
say "ID: #{droplet.id}"
|
61
61
|
say "Status: #{status_color}#{droplet.status}#{CLEAR}"
|
62
|
-
say "IP4: #{droplet_ip4_public}"
|
62
|
+
say "IP4: #{droplet_ip4_public}" unless droplet.networks.v4.empty?
|
63
63
|
say "IP6: #{droplet_ip6_public}" unless droplet.networks.v6.empty?
|
64
64
|
|
65
65
|
say "Private IP: #{droplet_private_ip}" if droplet_private_ip
|
@@ -10,13 +10,22 @@ module Tugboat
|
|
10
10
|
# Sets the digital ocean client into the environment for use
|
11
11
|
# later.
|
12
12
|
@access_token = env['config'].access_token
|
13
|
+
config_timeout = env['config'].timeout
|
14
|
+
|
15
|
+
env['barge'] = Barge::Client.new(access_token: @access_token,
|
16
|
+
timeout: config_timeout,
|
17
|
+
open_timeout: config_timeout)
|
13
18
|
|
14
|
-
env['barge'] = Barge::Client.new(access_token: @access_token)
|
15
19
|
env['droplet_kit'] = DropletKit::Client.new(access_token: @access_token)
|
16
20
|
|
21
|
+
env['droplet_kit'].connection.options.timeout = config_timeout.to_i
|
22
|
+
env['droplet_kit'].connection.options.open_timeout = config_timeout.to_i
|
23
|
+
|
17
24
|
env['barge'].faraday.use CustomLogger if ENV['DEBUG']
|
18
25
|
env['droplet_kit'].connection.use CustomLogger if ENV['DEBUG']
|
19
26
|
|
27
|
+
env['droplet_kit'].connection
|
28
|
+
|
20
29
|
@app.call(env)
|
21
30
|
end
|
22
31
|
end
|
@@ -3,13 +3,14 @@ module Tugboat
|
|
3
3
|
# Check if the client has set-up configuration yet.
|
4
4
|
class ListDroplets < Base
|
5
5
|
def call(env)
|
6
|
-
ocean = env['
|
6
|
+
ocean = env['droplet_kit']
|
7
7
|
|
8
8
|
verify_credentials(ocean)
|
9
9
|
|
10
|
-
droplet_list = get_droplet_list
|
10
|
+
droplet_list = get_droplet_list(ocean, env['per_page'])
|
11
11
|
|
12
12
|
has_one = false
|
13
|
+
|
13
14
|
droplet_list.each do |droplet|
|
14
15
|
has_one = true
|
15
16
|
|
@@ -25,7 +26,8 @@ module Tugboat
|
|
25
26
|
end
|
26
27
|
|
27
28
|
public_addr = droplet.networks.v4.find { |address| address.type == 'public' }
|
28
|
-
|
29
|
+
|
30
|
+
say "#{droplet.name} (ip: #{public_addr.ip_address}#{private_ip}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region.slug}, size: #{droplet.size_slug}, id: #{droplet.id}#{env['include_urls'] ? droplet_id_to_url(droplet.id) : ''})"
|
29
31
|
end
|
30
32
|
|
31
33
|
unless has_one
|
data/lib/tugboat/version.rb
CHANGED
data/spec/cli/add_key_spec.rb
CHANGED
@@ -23,15 +23,16 @@ describe Tugboat::CLI do
|
|
23
23
|
to_return(status: 201, body: fixture('create_ssh_key'), headers: {})
|
24
24
|
|
25
25
|
cli.options = cli.options.merge(key: ssh_public_key.to_s)
|
26
|
-
cli.add_key(ssh_key_name)
|
27
26
|
|
28
|
-
|
27
|
+
add_key_with_name_and_keystring = <<-eos
|
29
28
|
Queueing upload of SSH key 'macbook_pro'...SSH Key uploaded
|
30
29
|
|
31
30
|
Name: macbook_pro
|
32
31
|
ID: 3
|
33
32
|
eos
|
34
33
|
|
34
|
+
expect { cli.add_key(ssh_key_name) }.to output(add_key_with_name_and_keystring).to_stdout
|
35
|
+
|
35
36
|
expect(a_request(:post, 'https://api.digitalocean.com/v2/account/keys')).to have_been_made
|
36
37
|
end
|
37
38
|
|
@@ -52,23 +53,20 @@ ID: 3
|
|
52
53
|
headers: { 'Accept' => '*/*', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json' }).
|
53
54
|
to_return(status: 201, body: fixture('create_ssh_key_from_file'), headers: {})
|
54
55
|
|
55
|
-
expect($stdout).to receive(:print).exactly(4).times
|
56
|
-
expect($stdout).to receive(:print).with('Enter the path to your SSH key: ')
|
57
|
-
expect($stdout).to receive(:print).with("Queueing upload of SSH key '#{ssh_key_name}'...")
|
58
56
|
expect($stdin).to receive(:gets).and_return("#{fake_home}/.ssh/id_rsa.pub")
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
expect($stdout.string).to eq <<-eos
|
58
|
+
with_name_prompts_from_file_folder_stdout = <<-eos
|
63
59
|
Possible public key paths from #{fake_home}/.ssh:
|
64
60
|
|
65
61
|
#{fake_home}/.ssh/id_rsa.pub
|
66
62
|
|
67
|
-
SSH Key uploaded
|
63
|
+
Enter the path to your SSH key: Queueing upload of SSH key 'macbook_pro'...SSH Key uploaded
|
68
64
|
|
69
65
|
Name: cool_key
|
70
66
|
ID: 5
|
71
67
|
eos
|
68
|
+
|
69
|
+
expect { cli.add_key(ssh_key_name) }.to output(with_name_prompts_from_file_folder_stdout).to_stdout
|
72
70
|
end
|
73
71
|
|
74
72
|
after do
|
@@ -14,35 +14,20 @@ describe Tugboat::CLI do
|
|
14
14
|
with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
|
15
15
|
to_return(status: 200, body: fixture('show_droplets'), headers: {})
|
16
16
|
|
17
|
-
expect($stdout).to receive(:print).exactly(6).times
|
18
|
-
expect($stdout).to receive(:print).with('Enter your access token: ')
|
19
17
|
expect($stdin).to receive(:gets).and_return(access_token)
|
20
|
-
expect($
|
18
|
+
expect($stdin).to receive(:gets).and_return(timeout)
|
21
19
|
expect($stdin).to receive(:gets).and_return(ssh_key_path)
|
22
|
-
expect($stdout).to receive(:print).with('Enter your SSH user (optional, defaults to root): ')
|
23
20
|
expect($stdin).to receive(:gets).and_return(ssh_user)
|
24
|
-
expect($stdout).to receive(:print).with('Enter your SSH port number (optional, defaults to 22): ')
|
25
21
|
expect($stdin).to receive(:gets).and_return(ssh_port)
|
26
|
-
expect($stdout).to receive(:print).with('Enter your default region (optional, defaults to nyc1): ')
|
27
22
|
expect($stdin).to receive(:gets).and_return(region)
|
28
|
-
expect($stdout).to receive(:print).with('Enter your default image ID or image slug (optional, defaults to ubuntu-14-04-x64): ')
|
29
23
|
expect($stdin).to receive(:gets).and_return(image)
|
30
|
-
expect($stdout).to receive(:print).with('Enter your default size (optional, defaults to 512mb)): ')
|
31
24
|
expect($stdin).to receive(:gets).and_return(size)
|
32
|
-
expect($stdout).to receive(:print).with("Enter your default ssh key IDs (optional, defaults to none, array of IDs of ssh keys eg. ['1234']): ")
|
33
25
|
expect($stdin).to receive(:gets).and_return(ssh_key_id)
|
34
|
-
expect($stdout).to receive(:print).with('Enter your default for private networking (optional, defaults to false): ')
|
35
26
|
expect($stdin).to receive(:gets).and_return(private_networking)
|
36
|
-
expect($stdout).to receive(:print).with('Enter your default for enabling backups (optional, defaults to false): ')
|
37
27
|
expect($stdin).to receive(:gets).and_return(backups_enabled)
|
38
|
-
expect($stdout).to receive(:print).with('Enter your default for IPv6 (optional, defaults to false): ')
|
39
28
|
expect($stdin).to receive(:gets).and_return(ip6)
|
40
29
|
|
41
|
-
cli.authorize
|
42
|
-
|
43
|
-
expect($stdout.string).to include('Note: You can get your Access Token from https://cloud.digitalocean.com/settings/tokens/new')
|
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.')
|
30
|
+
expect { cli.authorize }.to output(/Note: You can get your Access Token from https:\/\/cloud.digitalocean.com\/settings\/tokens\/new/).to_stdout
|
46
31
|
|
47
32
|
config = YAML.load_file(tmp_path)
|
48
33
|
|
@@ -63,35 +48,20 @@ describe Tugboat::CLI do
|
|
63
48
|
with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => %r{Bearer}, 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
|
64
49
|
to_return(status: 200, body: fixture('show_droplets'), headers: {})
|
65
50
|
|
66
|
-
expect($stdout).to receive(:print).exactly(6).times
|
67
|
-
expect($stdout).to receive(:print).with('Enter your access token: ')
|
68
51
|
expect($stdin).to receive(:gets).and_return('')
|
69
|
-
expect($stdout).to receive(:print).with('Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa): ')
|
70
52
|
expect($stdin).to receive(:gets).and_return('')
|
71
|
-
expect($stdout).to receive(:print).with('Enter your SSH user (optional, defaults to root): ')
|
72
53
|
expect($stdin).to receive(:gets).and_return('')
|
73
|
-
expect($stdout).to receive(:print).with('Enter your SSH port number (optional, defaults to 22): ')
|
74
54
|
expect($stdin).to receive(:gets).and_return('')
|
75
|
-
expect($stdout).to receive(:print).with('Enter your default region (optional, defaults to nyc1): ')
|
76
55
|
expect($stdin).to receive(:gets).and_return('')
|
77
|
-
expect($stdout).to receive(:print).with('Enter your default image ID or image slug (optional, defaults to ubuntu-14-04-x64): ')
|
78
56
|
expect($stdin).to receive(:gets).and_return('')
|
79
|
-
expect($stdout).to receive(:print).with('Enter your default size (optional, defaults to 512mb)): ')
|
80
57
|
expect($stdin).to receive(:gets).and_return('')
|
81
|
-
expect($stdout).to receive(:print).with("Enter your default ssh key IDs (optional, defaults to none, array of IDs of ssh keys eg. ['1234']): ")
|
82
58
|
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
59
|
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
60
|
expect($stdin).to receive(:gets).and_return('')
|
87
|
-
expect($
|
61
|
+
expect($stdin).to receive(:gets).and_return('')
|
88
62
|
expect($stdin).to receive(:gets).and_return('')
|
89
63
|
|
90
|
-
cli.authorize
|
91
|
-
|
92
|
-
expect($stdout.string).to include('Note: You can get your Access Token from https://cloud.digitalocean.com/settings/tokens/new')
|
93
|
-
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`.")
|
94
|
-
expect($stdout.string).to include('Defaults can be changed at any time in your ~/.tugboat configuration file.')
|
64
|
+
expect { cli.authorize }.to output(/Note: You can get your Access Token from https:\/\/cloud.digitalocean.com\/settings\/tokens\/new/).to_stdout
|
95
65
|
|
96
66
|
config = YAML.load_file(tmp_path)
|
97
67
|
|