tugboat 2.0.0.RC1 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4a6516497a6285190e53a1e6209f4c3bc7ff38e
4
- data.tar.gz: 1deee8b54ce280230929f27e920fef46b6d471ff
3
+ metadata.gz: 7d9cd87077814b0c15d54c53ba161fffdf4adcd5
4
+ data.tar.gz: cea9da9936b38ff7b773643406cbf2ed6ac8b844
5
5
  SHA512:
6
- metadata.gz: 3f275a9150a93971d9a8e0067c09d51727162c2b97bd52c6acd42faead78c8fbcd713212343ace0c296fa347976ada8e9d5d99c2d7b0268d2f53108fe23ac424
7
- data.tar.gz: 4a77d1bd1b256ba368d04c722e13b85802f5344d80f69979ce0887517577dcf95a66507730bb350cd7f54a205c43a66e8b04004393b17784407663c5b6d0bc3a
6
+ metadata.gz: 04e3dd2f82fc781620cdea6ec5966b4e6ac836333d276f541bccfd526cc051d06adcbcfe25975ae5677757d046f52bd8d04e8bd911d33e8fac85e22a9e395ffb
7
+ data.tar.gz: 59aebcb1e96713bd589e071088a4c35af544b8b2d065ba0ef3e54f696622bb14edfaca431b8b19f3258f3796132182f717a4af3207781da8b028a57d2be9da44
data/CHANGELOG.md CHANGED
@@ -1,8 +1,26 @@
1
1
  # Change Log
2
2
 
3
+ ## [v2.0.0.RC1](https://github.com/pearkes/tugboat/tree/v2.0.0.RC1) (2015-10-20)
4
+
5
+ [Full Changelog](https://github.com/pearkes/tugboat/compare/v1.3.1...v2.0.0.RC1)
6
+
7
+ **Closed issues:**
8
+
9
+ - Possible to delete an image/snapshot? [\#177](https://github.com/pearkes/tugboat/issues/177)
10
+
11
+ **Merged pull requests:**
12
+
13
+ - Update gemspec [\#181](https://github.com/pearkes/tugboat/pull/181) ([petems](https://github.com/petems))
14
+
15
+ - API 2.0 Release Candidate PR [\#180](https://github.com/pearkes/tugboat/pull/180) ([petems](https://github.com/petems))
16
+
17
+ - Add CLI config spec and slight formatting changes [\#179](https://github.com/pearkes/tugboat/pull/179) ([petems](https://github.com/petems))
18
+
19
+ - Fix interactive prompt during authorize [\#175](https://github.com/pearkes/tugboat/pull/175) ([conorsch](https://github.com/conorsch))
20
+
3
21
  ## [v1.3.1](https://github.com/pearkes/tugboat/tree/v1.3.1) (2015-08-02)
4
22
 
5
- [Full Changelog](https://github.com/pearkes/tugboat/compare/v1.3.0...v1.3.1)
23
+ [Full Changelog](https://github.com/pearkes/tugboat/compare/v2.1.0.ALPHA...v1.3.1)
6
24
 
7
25
  **Closed issues:**
8
26
 
@@ -12,6 +30,10 @@
12
30
 
13
31
  - Removes wrong help messages for `images`. [\#173](https://github.com/pearkes/tugboat/pull/173) ([haihappen](https://github.com/haihappen))
14
32
 
33
+ ## [v2.1.0.ALPHA](https://github.com/pearkes/tugboat/tree/v2.1.0.ALPHA) (2015-07-20)
34
+
35
+ [Full Changelog](https://github.com/pearkes/tugboat/compare/v1.3.0...v2.1.0.ALPHA)
36
+
15
37
  ## [v1.3.0](https://github.com/pearkes/tugboat/tree/v1.3.0) (2015-07-19)
16
38
 
17
39
  [Full Changelog](https://github.com/pearkes/tugboat/compare/v1.2.0...v1.3.0)
@@ -38,12 +60,14 @@
38
60
 
39
61
  ## [v1.1.0](https://github.com/pearkes/tugboat/tree/v1.1.0) (2015-07-18)
40
62
 
41
- [Full Changelog](https://github.com/pearkes/tugboat/compare/v2.0.0.ALPHA...v1.1.0)
63
+ [Full Changelog](https://github.com/pearkes/tugboat/compare/v1.0.0...v1.1.0)
42
64
 
43
65
  **Closed issues:**
44
66
 
45
67
  - Unable to bundle to run tugboat from git repo version for testing [\#171](https://github.com/pearkes/tugboat/issues/171)
46
68
 
69
+ - 1.0.0 Release [\#125](https://github.com/pearkes/tugboat/issues/125)
70
+
47
71
  **Merged pull requests:**
48
72
 
49
73
  - Update ssh to private ip [\#172](https://github.com/pearkes/tugboat/pull/172) ([petems](https://github.com/petems))
data/README.md CHANGED
@@ -28,7 +28,7 @@ Run the configuration utility, `tugboat authorize`. You can grab your keys
28
28
  Enter your default region ID (optional, defaults to 1 (New York)):
29
29
  Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)):
30
30
  Enter your default size ID (optional, defaults to 66 (512MB)):
31
- Enter your default ssh key ID (optional, defaults to none):
31
+ Enter your default ssh key IDs (optional, defaults to '', comma separated string):
32
32
 
33
33
  Authentication with DigitalOcean was successful!
34
34
 
@@ -41,9 +41,9 @@ Tugboat will look for a .tugboat config file first in the current directory you'
41
41
  ### Retrieve a list of your droplets
42
42
 
43
43
  $ tugboat droplets
44
- pearkes-web-001 (ip: 30.30.30.1, status: active, region: 1, id: 13231511)
45
- pearkes-admin-001 (ip: 30.30.30.3, status: active, region: 1, id: 13231512)
46
- pearkes-api-001 (ip: 30.30.30.5, status: active, region: 1, id: 13231513)
44
+ pearkes-web-001 (ip: 30.30.30.1, status: active, region: nyc2, id: 13231511)
45
+ pearkes-admin-001 (ip: 30.30.30.3, status: active, region: nyc2, id: 13231512)
46
+ pearkes-api-001 (ip: 30.30.30.5, status: active, region: nyc2, id: 13231513)
47
47
 
48
48
  ### Fuzzy name matching
49
49
 
@@ -82,7 +82,7 @@ match.
82
82
 
83
83
  ### Create a droplet
84
84
 
85
- $ tugboat create pearkes-www-002 -s 64 -i 2676 -r 2 -k 11251
85
+ $ tugboat create pearkes-www-002 -s 512mb -i ubuntu-12-04-x64 -r nyc2 -k 11251
86
86
  Queueing creation of droplet 'pearkes-www-002'...done
87
87
 
88
88
  ### Info about a droplet
@@ -94,10 +94,11 @@ match.
94
94
  ID: 13231512
95
95
  Status: active
96
96
  IP: 30.30.30.3
97
- Region ID: 1
98
- Image ID: 25489
99
- Size ID: 66
100
97
  Backups Active: false
98
+ IP6: 2A03:B0C0:0001:00D0:0000:0000:0308:D001
99
+ Region: London 1 - lon1
100
+ Image: 6918990 - ubuntu-14-04-x64
101
+ Size: 1GB
101
102
 
102
103
  Print info in machine-readable format. The ``--porcelain`` flag silences extra output for easy parsing. Fuzzy name matching is not supported with the ``--porcelain`` flag.
103
104
 
@@ -105,10 +106,10 @@ Print info in machine-readable format. The ``--porcelain`` flag silences extra o
105
106
  name pearkes-admin-001
106
107
  id 13231512
107
108
  status active
108
- ip 30.30.30.3
109
- region_id 1
110
- image_id 25489
111
- size_id 66
109
+ ip4 30.30.30.3
110
+ region lon1
111
+ image 6918990
112
+ size 1gb
112
113
  backups_active false
113
114
 
114
115
  Print a single attribute.
@@ -148,44 +149,61 @@ Print a single attribute.
148
149
 
149
150
  ### List Available Images
150
151
 
151
- You can list images that you have created.
152
+ You can list all images
152
153
 
153
154
  $ tugboat images
154
- My Images:
155
- pearkes-admin-001 2013-05-19 (id: 13231512, distro: Ubuntu)
155
+ Showing both private and public images
156
+ Private Images:
157
+ My application image (id: 6376601, distro: Ubuntu)
158
+
159
+ Public Images:
160
+ 745.1.0 (alpha) (slug: coreos-alpha, id: 12789325, distro: CoreOS)
161
+ 723.3.0 (beta) (slug: coreos-beta, id: 12789350, distro: CoreOS)
162
+ 717.3.0 (stable) (slug: coreos-stable, id: 12789351, distro: CoreOS)
156
163
  ....
157
164
 
158
- Optionally, list images provided by DigitalOcean as well.
165
+ Or just list images that you have created.
159
166
 
160
- $ tugboat images --global
161
- My Images:
162
- pearkes-admin-001 2013-05-19 (id: 13231512, distro: Ubuntu)
167
+ $ tugboat images --show_just_private_images # or -p
168
+ Showing just private images
169
+ Private Images:
170
+ My application image (id: 6376601, distro: Ubuntu)
163
171
  ....
164
- Global Images:
165
- CentOS 5.8 x64 (id: 1601, distro: CentOS)
166
- ...
167
172
 
168
173
  ### List Available Sizes
169
174
 
170
175
  $ tugboat sizes
171
176
  Sizes:
172
- 512MB (id: 66)
173
- 1GB (id: 63)
177
+ Disk: 20GB, Memory: 512MB (slug: 512mb)
178
+ Disk: 30GB, Memory: 1024MB (slug: 1gb)
179
+ Disk: 40GB, Memory: 2048MB (slug: 2gb)
180
+ Disk: 60GB, Memory: 4096MB (slug: 4gb)
181
+ Disk: 80GB, Memory: 8192MB (slug: 8gb)
182
+ Disk: 160GB, Memory: 16384MB (slug: 16gb)
183
+ Disk: 320GB, Memory: 32768MB (slug: 32gb)
184
+ Disk: 480GB, Memory: 49152MB (slug: 48gb)
185
+ Disk: 640GB, Memory: 65536MB (slug: 64gb)
174
186
  ...
175
187
 
176
188
  ### List Available Regions
177
189
 
178
190
  $ tugboat regions
179
191
  Regions:
180
- New York 1 (id: 1) (slug: nyc1)
181
- Amsterdam 1 (id: 2) (slug: ams1)
182
- San Francisco 1 (id: 3) (slug: sfo1)
192
+ Amsterdam 1 (slug: ams1)
193
+ Amsterdam 2 (slug: ams2)
194
+ Amsterdam 3 (slug: ams3)
195
+ London 1 (slug: lon1)
196
+ New York 1 (slug: nyc1)
197
+ New York 2 (slug: nyc2)
198
+ New York 3 (slug: nyc3)
199
+ San Francisco 1 (slug: sfo1)
200
+ Singapore 1 (slug: sgp1)
183
201
 
184
202
  ### List SSH Keys
185
203
 
186
204
  $ tugboat keys
187
205
  Keys:
188
- pearkes (id: 10501)
206
+ Name: pearkes, (id: 231192), fingerprint: 3b:16:bf:e4:8b:00:8b:b8:59:8c:a9:d3:f0:19:45:fa
189
207
  ...
190
208
 
191
209
  ### Wait for Droplet State
@@ -213,7 +231,6 @@ For a complete overview of all of the available commands, run:
213
231
 
214
232
  $ tugboat help
215
233
 
216
-
217
234
  Depending on your local configuration, you may need to install a CA bundle (OS X only) using [homebrew](http://brew.sh/) to communicate with DigitalOcean through SSL/TLS:
218
235
 
219
236
  $ brew install curl-ca-bundle
@@ -226,12 +243,8 @@ After installation, source the bundle path in your `.bash_profile`/`.bashrc`:
226
243
 
227
244
  Yes, please!
228
245
 
229
- It's very helpful if you can run `DEBUG=1 tugboat ...` with the command
230
- that is causing you issues, and then include that in the issue.
231
-
232
246
  You can create a new issue [here](https://github.com/pearkes/tugboat/issues/new). Thank you!
233
247
 
234
248
  ## Contributing
235
249
 
236
- See the [contributing guide](CONTRIBUTING.md).
237
-
250
+ See the [contributing guide](CONTRIBUTING.md).
data/lib/tugboat/cli.rb CHANGED
@@ -36,6 +36,7 @@ module Tugboat
36
36
  "
37
37
  def authorize
38
38
  Middleware.sequence_authorize.call({
39
+ "tugboat_action" => __method__,
39
40
  "user_quiet" => options[:quiet]
40
41
  })
41
42
  end
@@ -51,6 +52,7 @@ module Tugboat
51
52
  :desc => "Hide your API keys"
52
53
  def config
53
54
  Middleware.sequence_config.call({
55
+ "tugboat_action" => __method__,
54
56
  "user_hide_keys" => options[:hide],
55
57
  })
56
58
  end
@@ -62,14 +64,22 @@ module Tugboat
62
64
  "
63
65
  def verify
64
66
  Middleware.sequence_verify.call({
67
+ "tugboat_action" => __method__,
65
68
  "user_quiet" => options[:quiet]
66
69
  })
67
70
  end
68
71
 
69
- desc "droplets", "Retrieve a list of your droplets"
72
+ method_option "include_urls",
73
+ :type => :boolean,
74
+ :default => false,
75
+ :aliases => "-i",
76
+ :desc => "Include URLs for the droplets (can be opened in a browser)"
77
+ desc "droplets [OPTIONS]", "Retrieve a list of your droplets"
70
78
  def droplets
71
79
  Middleware.sequence_list_droplets.call({
72
- "user_quiet" => options[:quiet]
80
+ "tugboat_action" => __method__,
81
+ "user_quiet" => options[:quiet],
82
+ "include_urls" => options["include_urls"]
73
83
  })
74
84
  end
75
85
 
@@ -81,6 +91,7 @@ module Tugboat
81
91
  :desc => "Show just private images"
82
92
  def images
83
93
  Middleware.sequence_list_images.call({
94
+ "tugboat_action" => __method__,
84
95
  "user_show_just_private_images" => options[:show_just_private_images],
85
96
  "user_quiet" => options[:quiet]
86
97
  })
@@ -114,10 +125,11 @@ module Tugboat
114
125
  :desc => "Custom SSH options"
115
126
  method_option "ssh_command",
116
127
  :type => :string,
117
- :aliases => "-c",
128
+ :aliases => [ "-c", "-y" ,],
118
129
  :desc => "Command to run on the droplet"
119
130
  def ssh(name=nil)
120
131
  Middleware.sequence_ssh_droplet.call({
132
+ "tugboat_action" => __method__,
121
133
  "user_droplet_id" => options[:id],
122
134
  "user_droplet_name" => options[:name],
123
135
  "user_droplet_fuzzy_name" => name,
@@ -134,15 +146,15 @@ module Tugboat
134
146
  method_option "size",
135
147
  :type => :numeric,
136
148
  :aliases => "-s",
137
- :desc => "The size_id of the droplet"
149
+ :desc => "The size slug of the droplet"
138
150
  method_option "image",
139
151
  :type => :numeric,
140
152
  :aliases => "-i",
141
- :desc => "The image_id of the droplet"
153
+ :desc => "The image slug of the droplet"
142
154
  method_option "region",
143
155
  :type => :numeric,
144
156
  :aliases => "-r",
145
- :desc => "The region_id of the droplet"
157
+ :desc => "The region slug of the droplet"
146
158
  method_option "keys",
147
159
  :type => :string,
148
160
  :aliases => "-k",
@@ -151,6 +163,14 @@ module Tugboat
151
163
  :type => :boolean,
152
164
  :aliases => "-p",
153
165
  :desc => "Enable private networking on the droplet"
166
+ method_option "ip6",
167
+ :type => :boolean,
168
+ :aliases => "-l",
169
+ :desc => "Enable IP6 on the droplet"
170
+ method_option "user_data",
171
+ :type => :string,
172
+ :aliases => "-u",
173
+ :desc => "Location of a file to read and use as user data"
154
174
  method_option "backups_enabled",
155
175
  :type => :boolean,
156
176
  :aliases => "-b",
@@ -163,11 +183,14 @@ module Tugboat
163
183
  end
164
184
 
165
185
  Middleware.sequence_create_droplet.call({
166
- "create_droplet_size_id" => options[:size],
167
- "create_droplet_image_id" => options[:image],
168
- "create_droplet_region_id" => options[:region],
186
+ "tugboat_action" => __method__,
169
187
  "create_droplet_ssh_key_ids" => options[:keys],
188
+ "create_droplet_size_slug" => options[:size],
189
+ "create_droplet_image_slug" => options[:image],
190
+ "create_droplet_region_slug" => options[:region],
170
191
  "create_droplet_private_networking" => options[:private_networking],
192
+ "create_droplet_ip6" => options[:ip6],
193
+ "create_droplet_user_data" => options[:user_data],
171
194
  "create_droplet_backups_enabled" => options[:backups_enabled],
172
195
  "create_droplet_name" => name,
173
196
  "user_quiet" => options[:quiet]
@@ -185,7 +208,7 @@ module Tugboat
185
208
  :desc => "The exact name of the droplet"
186
209
  method_option "confirm",
187
210
  :type => :boolean,
188
- :aliases => "-c",
211
+ :aliases => [ "-c", "-y" ,],
189
212
  :desc => "Skip confirmation of the action"
190
213
  method_option "image_id",
191
214
  :type => :numeric,
@@ -197,6 +220,7 @@ module Tugboat
197
220
  :desc => "The exact name of the image"
198
221
  def rebuild(name=nil, image_name=nil)
199
222
  Middleware.sequence_rebuild_droplet.call({
223
+ "tugboat_action" => __method__,
200
224
  "user_droplet_id" => options[:id],
201
225
  "user_droplet_name" => options[:name],
202
226
  "user_droplet_fuzzy_name" => name,
@@ -219,10 +243,11 @@ module Tugboat
219
243
  :desc => "The exact name of the droplet"
220
244
  method_option "confirm",
221
245
  :type => :boolean,
222
- :aliases => "-c",
246
+ :aliases => [ "-c", "-y" ,],
223
247
  :desc => "Skip confirmation of the action"
224
248
  def destroy(name=nil)
225
249
  Middleware.sequence_destroy_droplet.call({
250
+ "tugboat_action" => __method__,
226
251
  "user_droplet_id" => options[:id],
227
252
  "user_droplet_name" => options[:name],
228
253
  "user_confirm_action" => options[:confirm],
@@ -242,10 +267,11 @@ module Tugboat
242
267
  :desc => "The exact name of the image"
243
268
  method_option "confirm",
244
269
  :type => :boolean,
245
- :aliases => "-c",
270
+ :aliases => [ "-c", "-y" ,],
246
271
  :desc => "Skip confirmation of the action"
247
272
  def destroy_image(name=nil)
248
273
  Middleware.sequence_destroy_image.call({
274
+ "tugboat_action" => __method__,
249
275
  "user_image_id" => options[:id],
250
276
  "user_image_name" => options[:name],
251
277
  "user_image_fuzzy_name" => name,
@@ -269,6 +295,7 @@ module Tugboat
269
295
  :desc => "Perform a hard restart"
270
296
  def restart(name=nil)
271
297
  Middleware.sequence_restart_droplet.call({
298
+ "tugboat_action" => __method__,
272
299
  "user_droplet_id" => options[:id],
273
300
  "user_droplet_name" => options[:name],
274
301
  "user_droplet_hard" => options[:hard],
@@ -292,6 +319,7 @@ module Tugboat
292
319
  :desc => "Perform a hard shutdown"
293
320
  def halt(name=nil)
294
321
  Middleware.sequence_halt_droplet.call({
322
+ "tugboat_action" => __method__,
295
323
  "user_droplet_id" => options[:id],
296
324
  "user_droplet_name" => options[:name],
297
325
  "user_droplet_hard" => options[:hard],
@@ -318,6 +346,7 @@ module Tugboat
318
346
  :desc => "Give the output in an easy-to-parse format for scripts."
319
347
  def info(name=nil)
320
348
  Middleware.sequence_info_droplet.call({
349
+ "tugboat_action" => __method__,
321
350
  "user_droplet_id" => options[:id],
322
351
  "user_droplet_name" => options[:name],
323
352
  "user_droplet_fuzzy_name" => name,
@@ -338,6 +367,7 @@ module Tugboat
338
367
  :desc => "The exact name of the image"
339
368
  def info_image(name=nil)
340
369
  Middleware.sequence_info_image.call({
370
+ "tugboat_action" => __method__,
341
371
  "user_image_id" => options[:id],
342
372
  "user_image_name" => options[:name],
343
373
  "user_image_fuzzy_name" => name,
@@ -356,6 +386,7 @@ module Tugboat
356
386
  :desc => "The exact name of the droplet"
357
387
  def snapshot(snapshot_name, name=nil)
358
388
  Middleware.sequence_snapshot_droplet.call({
389
+ "tugboat_action" => __method__,
359
390
  "user_droplet_id" => options[:id],
360
391
  "user_droplet_name" => options[:name],
361
392
  "user_droplet_fuzzy_name" => name,
@@ -366,7 +397,9 @@ module Tugboat
366
397
 
367
398
  desc "keys", "Show available SSH keys"
368
399
  def keys
369
- Middleware.sequence_ssh_keys.call({})
400
+ Middleware.sequence_ssh_keys.call({
401
+ "tugboat_action" => __method__,
402
+ })
370
403
  end
371
404
 
372
405
  desc "add-key KEY-NAME", "Upload an ssh public key to DigitalOcean, to be assigned to a droplet later"
@@ -383,6 +416,7 @@ module Tugboat
383
416
  :desc => "The path to the ssh key"
384
417
  def add_key(name)
385
418
  Middleware.sequence_add_key.call({
419
+ "tugboat_action" => __method__,
386
420
  "add_key_name" => name,
387
421
  "add_key_pub_key" => options[:key],
388
422
  "add_key_file_path" => options[:path],
@@ -393,6 +427,7 @@ module Tugboat
393
427
  desc "regions", "Show regions"
394
428
  def regions
395
429
  Middleware.sequence_regions.call({
430
+ "tugboat_action" => __method__,
396
431
  "user_quiet" => options[:quiet]
397
432
  })
398
433
  end
@@ -405,6 +440,7 @@ module Tugboat
405
440
  desc "sizes", "Show available droplet sizes"
406
441
  def sizes
407
442
  Middleware.sequence_sizes.call({
443
+ "tugboat_action" => __method__,
408
444
  "user_quiet" => options[:quiet]
409
445
  })
410
446
  end
@@ -420,6 +456,7 @@ module Tugboat
420
456
  :desc => "The exact name of the droplet"
421
457
  def start(name=nil)
422
458
  Middleware.sequence_start_droplet.call({
459
+ "tugboat_action" => __method__,
423
460
  "user_droplet_id" => options[:id],
424
461
  "user_droplet_name" => options[:name],
425
462
  "user_droplet_fuzzy_name" => name,
@@ -443,6 +480,7 @@ module Tugboat
443
480
  :desc => "The size_id to resize the droplet to"
444
481
  def resize(name=nil)
445
482
  Middleware.sequence_resize_droplet.call({
483
+ "tugboat_action" => __method__,
446
484
  "user_droplet_id" => options[:id],
447
485
  "user_droplet_name" => options[:name],
448
486
  "user_droplet_size" => options[:size],
@@ -463,6 +501,7 @@ module Tugboat
463
501
 
464
502
  def password_reset(name=nil)
465
503
  Middleware.sequence_password_reset.call({
504
+ "tugboat_action" => __method__,
466
505
  "user_droplet_id" => options[:id],
467
506
  "user_droplet_name" => options[:name],
468
507
  "user_droplet_fuzzy_name" => name,
@@ -487,6 +526,7 @@ module Tugboat
487
526
 
488
527
  def wait(name=nil)
489
528
  Middleware.sequence_wait.call({
529
+ "tugboat_action" => __method__,
490
530
  "user_droplet_id" => options[:id],
491
531
  "user_droplet_name" => options[:name],
492
532
  "user_droplet_desired_state" => options[:state],
@@ -16,8 +16,10 @@ module Tugboat
16
16
  DEFAULT_IMAGE = 'ubuntu-14-04-x64'
17
17
  DEFAULT_SIZE = '512mb'
18
18
  DEFAULT_SSH_KEY = ''
19
+ DEFAULT_IP6 = 'false'
19
20
  DEFAULT_PRIVATE_NETWORKING = 'false'
20
21
  DEFAULT_BACKUPS_ENABLED = 'false'
22
+ DEFAULT_USER_DATA = nil
21
23
 
22
24
  # Load config file from current directory, if not exit load from user's home directory
23
25
  def initialize
@@ -38,7 +40,7 @@ module Tugboat
38
40
  end
39
41
 
40
42
  def access_token
41
- @data['authentication']['access_token']
43
+ env_access_token || @data['authentication']['access_token']
42
44
  end
43
45
 
44
46
  def ssh_key_path
@@ -73,6 +75,14 @@ module Tugboat
73
75
  @data['defaults'].nil? ? DEFAULT_SSH_KEY : @data['defaults']['ssh_key']
74
76
  end
75
77
 
78
+ def default_ip6
79
+ @data['defaults'].nil? ? DEFAULT_IP6 : @data['defaults']['ip6']
80
+ end
81
+
82
+ def default_user_data
83
+ @data['defaults'].nil? ? DEFAULT_USER_DATA : @data['defaults']['user_data']
84
+ end
85
+
76
86
  def default_private_networking
77
87
  @data['defaults'].nil? ? DEFAULT_PRIVATE_NETWORKING : @data['defaults']['private_networking']
78
88
  end
@@ -81,6 +91,10 @@ module Tugboat
81
91
  @data['defaults'].nil? ? DEFAULT_BACKUPS_ENABLED : @data['defaults']['backups_enabled']
82
92
  end
83
93
 
94
+ def env_access_token
95
+ ENV['DO_API_TOKEN'] unless ENV['DO_API_TOKEN'].to_s.empty?
96
+ end
97
+
84
98
  # Re-runs initialize
85
99
  def reset!
86
100
  self.send(:initialize)
@@ -17,7 +17,7 @@ module Tugboat
17
17
  region = ask "Enter your default region (optional, defaults to nyc1):"
18
18
  image = ask "Enter your default image ID or image slug (optional, defaults to ubuntu-14-04-x64):"
19
19
  size = ask "Enter your default size (optional, defaults to 512mb)):"
20
- ssh_key = ask "Enter your default ssh key ID (optional, defaults to none):"
20
+ ssh_key = ask "Enter your default ssh key IDs (optional, defaults to none, comma separated string):"
21
21
  private_networking = ask "Enter your default for private networking (optional, defaults to false):"
22
22
  backups_enabled = ask "Enter your default for enabling backups (optional, defaults to false):"
23
23
 
@@ -6,41 +6,62 @@ module Tugboat
6
6
 
7
7
  say "Queueing creation of droplet '#{env["create_droplet_name"]}'...", nil, false
8
8
 
9
- env["create_droplet_region_id"] ?
10
- droplet_region_id = env["create_droplet_region_id"] :
11
- droplet_region_id = env["config"].default_region
9
+ env["create_droplet_region_slug"] ?
10
+ droplet_region_slug = env["create_droplet_region_slug"] :
11
+ droplet_region_slug = env["config"].default_region
12
12
 
13
- env["create_droplet_image_id"] ?
14
- droplet_image_id = env["create_droplet_image_id"] :
15
- droplet_image_id = env["config"].default_image
13
+ env["create_droplet_image_slug"] ?
14
+ droplet_image_slug = env["create_droplet_image_slug"] :
15
+ droplet_image_slug = env["config"].default_image
16
16
 
17
- env["create_droplet_size_id"] ?
18
- droplet_size_id = env["create_droplet_size_id"] :
19
- droplet_size_id = env["config"].default_size
17
+ env["create_droplet_size_slug"] ?
18
+ droplet_size_slug = env["create_droplet_size_slug"] :
19
+ droplet_size_slug = env["config"].default_size
20
20
 
21
21
  env["create_droplet_ssh_key_ids"] ?
22
- droplet_ssh_key_id = env["create_droplet_ssh_key_ids"] :
23
- droplet_ssh_key_id = env["config"].default_ssh_key
22
+ droplet_ssh_key_ids = env["create_droplet_ssh_key_ids"] :
23
+ droplet_ssh_key_ids = env["config"].default_ssh_key
24
24
 
25
25
  env["create_droplet_private_networking"] ?
26
26
  droplet_private_networking = env["create_droplet_private_networking"] :
27
27
  droplet_private_networking = env["config"].default_private_networking
28
28
 
29
+ env["create_droplet_ip6"] ?
30
+ droplet_ip6 = env["create_droplet_ip6"] :
31
+ droplet_ip6 = env["config"].default_ip6
32
+
33
+ env["create_droplet_user_data"] ?
34
+ droplet_user_data = env["create_droplet_user_data"] :
35
+ droplet_user_data = env["config"].default_user_data
36
+
37
+ if droplet_user_data
38
+ unless File.file?(droplet_user_data)
39
+ say "Could not find file: #{droplet_user_data}, check your user_data setting"
40
+ exit 1
41
+ else
42
+ user_data_string = File.open(droplet_user_data, 'rb') { |f| f.read }
43
+ end
44
+ end
45
+
29
46
  env["create_droplet_backups_enabled"] ?
30
47
  droplet_backups_enabled = env["create_droplet_backups_enabled"] :
31
48
  droplet_backups_enabled = env["config"].default_backups_enabled
32
49
 
33
- droplet_ssh_key_id = nil if droplet_ssh_key_id.empty?
50
+ droplet_key_array = droplet_ssh_key_ids.split(',')
51
+
52
+ droplet_key_array = nil if [droplet_key_array].empty?
53
+
34
54
 
35
55
  create_opts = {
36
56
  :name => env["create_droplet_name"],
37
- :size => droplet_size_id,
38
- :image => "#{droplet_image_id}",
39
- :region => droplet_region_id,
40
- :ssh_keys => [droplet_ssh_key_id],
57
+ :size => droplet_size_slug,
58
+ :image => "#{droplet_image_slug}",
59
+ :region => droplet_region_slug,
60
+ :ssh_keys => droplet_key_array,
41
61
  :private_networking => droplet_private_networking,
42
62
  :backups_enabled => droplet_backups_enabled,
43
- :ipv6 => nil,
63
+ :ipv6 => droplet_ip6,
64
+ :user_data => user_data_string,
44
65
  }
45
66
 
46
67
  response = ocean.droplet.create(create_opts)
@@ -12,7 +12,10 @@ module Tugboat
12
12
  # First, if nothing is provided to us, we should quit and
13
13
  # let the user know.
14
14
  if !user_fuzzy_name && !user_droplet_name && !user_droplet_id
15
- say "Tugboat attempted to find a droplet with no arguments. Try `tugboat help`", :red
15
+
16
+ say "Tugboat attempted to find a droplet with no arguments.", :red
17
+ say "Try running `tugboat #{env['tugboat_action']} dropletname`", :green
18
+ say "For more help run: `tugboat help #{env['tugboat_action']}`", :blue
16
19
  exit 1
17
20
  end
18
21
 
@@ -113,10 +116,17 @@ module Tugboat
113
116
  end
114
117
  say
115
118
  choice = ask "Please choose a droplet:", :limited_to => choices
119
+ for ip_list in found_droplets[choice.to_i].networks.v4 do
120
+ if ip_list.type == "private"
121
+ private_ip = ip_list.ip_address
122
+ elsif ip_list.type == "public"
123
+ public_ip = ip_list.ip_address
124
+ end
125
+ end
116
126
  env["droplet_id"] = found_droplets[choice.to_i].id
117
127
  env["droplet_name"] = found_droplets[choice.to_i].name
118
- env["droplet_ip"] = found_droplets[choice.to_i].ip_address
119
- env["droplet_ip_private"] = found_droplets[choice.to_i].private_ip_address
128
+ env["droplet_ip"] = public_ip
129
+ env["droplet_ip_private"] = private_ip
120
130
  env["droplet_status"] = found_droplets[choice.to_i].status
121
131
  end
122
132
 
@@ -11,7 +11,9 @@ module Tugboat
11
11
  # First, if nothing is provided to us, we should quit and
12
12
  # let the user know.
13
13
  if !user_fuzzy_name && !user_image_name && !user_image_id
14
- say "Tugboat attempted to find an image with no arguments. Try `tugboat help`", :red
14
+ say "Tugboat attempted to find an image with no arguments.", :red
15
+ say "Try running `tugboat #{env['tugboat_action']} imagename`", :green
16
+ say "For more help run: `tugboat help #{env['tugboat_action']}`", :blue
15
17
  exit 1
16
18
  end
17
19
 
@@ -39,7 +39,7 @@ module Tugboat
39
39
  ["ip6", droplet_ip6_public],
40
40
  ["private_ip", droplet_private_ip],
41
41
  ["region", droplet.region.slug],
42
- ["Image", droplet.image.id],
42
+ ["image", droplet.image.id],
43
43
  ["size", droplet.size_slug],
44
44
  ["backups_active", !droplet.backup_ids.empty?]
45
45
  ]
@@ -69,8 +69,14 @@ module Tugboat
69
69
  say "Private IP: #{droplet_private_ip}"
70
70
  end
71
71
 
72
+ if droplet.image.slug.nil?
73
+ image_description = droplet.image.name
74
+ else
75
+ image_description = droplet.image.slug
76
+ end
77
+
72
78
  say "Region: #{droplet.region.name} - #{droplet.region.slug}"
73
- say "Image: #{droplet.image.id} - #{droplet.image.name}"
79
+ say "Image: #{droplet.image.id} - #{image_description}"
74
80
  say "Size: #{droplet.size_slug.upcase}"
75
81
  say "Backups Active: #{!droplet.backup_ids.empty?}"
76
82
  end
@@ -17,6 +17,7 @@ module Tugboat
17
17
  say "Name: #{image.name}"
18
18
  say "ID: #{image.id}"
19
19
  say "Distribution: #{image.distribution}"
20
+ say "Min Disk Size: #{image.min_disk_size}GB"
20
21
 
21
22
  @app.call(env)
22
23
  end
@@ -25,12 +25,18 @@ module Tugboat
25
25
  end
26
26
 
27
27
  public_addr = droplet.networks.v4.detect { |address| address.type == 'public' }
28
- say "#{droplet.name} (ip: #{public_addr.ip_address}#{private_ip}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region.slug}, id: #{droplet.id})"
28
+ say "#{droplet.name} (ip: #{public_addr.ip_address}#{private_ip}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region.slug}, id: #{droplet.id}#{env["include_urls"] ? droplet_id_to_url(droplet.id) : '' })"
29
29
  end
30
30
  end
31
31
 
32
32
  @app.call(env)
33
33
  end
34
+
35
+ private
36
+
37
+ def droplet_id_to_url(id)
38
+ ", url: 'https://cloud.digitalocean.com/droplets/#{id}'"
39
+ end
34
40
  end
35
41
  end
36
42
  end
@@ -2,7 +2,7 @@ module Tugboat
2
2
  module Middleware
3
3
  class SSHDroplet < Base
4
4
  def call(env)
5
- say "Executing SSH #{env["droplet_name"]}..."
5
+ say "Executing SSH on Droplet #{env["droplet_name"]}..."
6
6
 
7
7
  options = [
8
8
  "-o", "IdentitiesOnly=yes",
@@ -44,6 +44,8 @@ module Tugboat
44
44
 
45
45
  host_string = "#{ssh_user}@#{host_ip}"
46
46
 
47
+ say "Attempting SSH: #{host_string}"
48
+
47
49
  options << host_string
48
50
 
49
51
  if env["user_droplet_ssh_command"]
@@ -1,3 +1,3 @@
1
1
  module Tugboat
2
- VERSION = "2.0.0.RC1"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -39,7 +39,9 @@ ID: 3
39
39
  before :each do
40
40
  allow(ENV).to receive(:[]).with('HOME').and_return(fake_home)
41
41
  allow(ENV).to receive(:[]).with('DEBUG').and_return(nil)
42
+ allow(ENV).to receive(:[]).with('DO_API_TOKEN').and_return(nil)
42
43
  allow(ENV).to receive(:[]).with('http_proxy').and_return(nil)
44
+
43
45
  FileUtils.mkdir_p "#{fake_home}/.ssh"
44
46
  File.open("#{fake_home}/.ssh/id_rsa.pub", 'w') {|f| f.write("ssh-dss A456= user@host") }
45
47
  end
@@ -30,7 +30,7 @@ describe Tugboat::CLI do
30
30
  expect($stdin).to receive(:gets).and_return(image)
31
31
  expect($stdout).to receive(:print).with("Enter your default size (optional, defaults to 512mb)): ")
32
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): ")
33
+ expect($stdout).to receive(:print).with("Enter your default ssh key IDs (optional, defaults to none, comma separated string): ")
34
34
  expect($stdin).to receive(:gets).and_return(ssh_key_id)
35
35
  expect($stdout).to receive(:print).with("Enter your default for private networking (optional, defaults to false): ")
36
36
  expect($stdin).to receive(:gets).and_return(private_networking)
@@ -76,7 +76,7 @@ describe Tugboat::CLI do
76
76
  expect($stdin).to receive(:gets).and_return('')
77
77
  expect($stdout).to receive(:print).with("Enter your default size (optional, defaults to 512mb)): ")
78
78
  expect($stdin).to receive(:gets).and_return('')
79
- expect($stdout).to receive(:print).with("Enter your default ssh key ID (optional, defaults to none): ")
79
+ expect($stdout).to receive(:print).with("Enter your default ssh key IDs (optional, defaults to none, comma separated string): ")
80
80
  expect($stdin).to receive(:gets).and_return('')
81
81
  expect($stdout).to receive(:print).with("Enter your default for private networking (optional, defaults to false): ")
82
82
  expect($stdin).to receive(:gets).and_return('')
@@ -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(:post, "https://api.digitalocean.com/v2/droplets").
9
- with(:body => "{\"name\":\"foo\",\"size\":\"512mb\",\"image\":\"ubuntu-14-04-x64\",\"region\":\"nyc2\",\"ssh_keys\":[\"1234\"],\"private_networking\":\"false\",\"backups_enabled\":\"false\",\"ipv6\":null}",
9
+ with(:body => "{\"name\":\"foo\",\"size\":\"512mb\",\"image\":\"ubuntu-14-04-x64\",\"region\":\"nyc2\",\"ssh_keys\":[\"1234\"],\"private_networking\":\"false\",\"backups_enabled\":\"false\",\"ipv6\":null,\"user_data\":null}",
10
10
  :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'}).
11
11
  to_return(:status => 200, :body => fixture('create_droplet'), :headers => {})
12
12
 
@@ -19,7 +19,7 @@ Queueing creation of droplet '#{droplet_name}'...Droplet created!
19
19
 
20
20
  it "with args does not use defaults from configuration" do
21
21
  stub_request(:post, "https://api.digitalocean.com/v2/droplets").
22
- with(:body => "{\"name\":\"example.com\",\"size\":\"1gb\",\"image\":\"ubuntu-12-04-x64\",\"region\":\"nyc3\",\"ssh_keys\":[\"foo_bar_key\"],\"private_networking\":\"false\",\"backups_enabled\":\"false\",\"ipv6\":null}",
22
+ with(:body => "{\"name\":\"example.com\",\"size\":\"1gb\",\"image\":\"ubuntu-12-04-x64\",\"region\":\"nyc3\",\"ssh_keys\":[\"foo_bar_key\"],\"private_networking\":\"false\",\"backups_enabled\":\"false\",\"ipv6\":null,\"user_data\":null}",
23
23
  :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'}).
24
24
  to_return(:status => 200, :body => fixture('create_droplet'), :headers => {})
25
25
 
@@ -32,8 +32,48 @@ Queueing creation of droplet 'example.com'...Droplet created!
32
32
 
33
33
  end
34
34
 
35
+ it "with ip6 enable args" do
36
+ stub_request(:post, "https://api.digitalocean.com/v2/droplets").
37
+ with(:body => "{\"name\":\"example.com\",\"size\":\"512mb\",\"image\":\"ubuntu-14-04-x64\",\"region\":\"nyc2\",\"ssh_keys\":[\"1234\"],\"private_networking\":\"false\",\"backups_enabled\":\"false\",\"ipv6\":\"true\",\"user_data\":null}",
38
+ :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'}).
39
+ to_return(:status => 200, :body => fixture('create_droplet'), :headers => {})
40
+
41
+ @cli.options = @cli.options.merge(:ip6 => 'true')
42
+ @cli.create('example.com')
43
+
44
+ expect($stdout.string).to eq <<-eos
45
+ Queueing creation of droplet 'example.com'...Droplet created!
46
+ eos
47
+
48
+ end
49
+
50
+ it "with user data args" do
51
+ stub_request(:post, "https://api.digitalocean.com/v2/droplets").
52
+ with(:body => "{\"name\":\"example.com\",\"size\":\"512mb\",\"image\":\"ubuntu-14-04-x64\",\"region\":\"nyc2\",\"ssh_keys\":[\"1234\"],\"private_networking\":\"false\",\"backups_enabled\":\"false\",\"ipv6\":null,\"user_data\":\"#!/bin/bash\\n\\necho \\\"Hello world\\\"\"}",
53
+ :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'}).
54
+ to_return(:status => 200, :body => fixture('create_droplet'), :headers => {})
55
+
56
+ @cli.options = @cli.options.merge(:user_data => project_path + "/spec/fixtures/user_data.sh")
57
+ @cli.create('example.com')
58
+
59
+ expect($stdout.string).to eq <<-eos
60
+ Queueing creation of droplet 'example.com'...Droplet created!
61
+ eos
62
+
63
+ end
64
+
65
+ it "fails when user data file does not exist" do
66
+ @cli.options = @cli.options.merge(:user_data => "/foo/bar/baz.sh")
67
+ expect {@cli.create("example.com")}.to raise_error(SystemExit)
68
+
69
+ expect($stdout.string).to eq <<-eos
70
+ Queueing creation of droplet 'example.com'...Could not find file: /foo/bar/baz.sh, check your user_data setting
71
+ eos
72
+
73
+ end
74
+
35
75
  it "doesn't create a droplet when mistyping help command" do
36
- help_text = "Usage:\n rspec create NAME\n\nOptions:\n -s, [--size=N] # The size_id of the droplet\n -i, [--image=N] # The image_id of the droplet\n -r, [--region=N] # The region_id of the droplet\n -k, [--keys=KEYS] # A comma separated list of SSH key ids to add to the droplet\n -p, [--private-networking] # Enable private networking on the droplet\n -b, [--backups-enabled] # Enable backups on the droplet\n -q, [--quiet] \n\nCreate a droplet.\n"
76
+ help_text = "Usage:\n rspec create NAME\n\nOptions:\n -s, [--size=N] # The size slug of the droplet\n -i, [--image=N] # The image slug of the droplet\n -r, [--region=N] # The region slug of the droplet\n -k, [--keys=KEYS] # A comma separated list of SSH key ids to add to the droplet\n -p, [--private-networking] # Enable private networking on the droplet\n -l, [--ip6] # Enable IP6 on the droplet\n -u, [--user-data=USER_DATA] # Location of a file to read and use as user data\n -b, [--backups-enabled] # Enable backups on the droplet\n -q, [--quiet] \n\nCreate a droplet.\n"
37
77
 
38
78
  @cli.create('help')
39
79
  expect($stdout.string).to eq help_text
@@ -47,7 +87,7 @@ Queueing creation of droplet 'example.com'...Droplet created!
47
87
 
48
88
  it "does not clobber named droplets that contain the word help" do
49
89
  stub_request(:post, "https://api.digitalocean.com/v2/droplets").
50
- with(:body => "{\"name\":\"somethingblahblah--help\",\"size\":\"512mb\",\"image\":\"ubuntu-14-04-x64\",\"region\":\"nyc2\",\"ssh_keys\":[\"1234\"],\"private_networking\":\"false\",\"backups_enabled\":\"false\",\"ipv6\":null}",
90
+ with(:body => "{\"name\":\"somethingblahblah--help\",\"size\":\"512mb\",\"image\":\"ubuntu-14-04-x64\",\"region\":\"nyc2\",\"ssh_keys\":[\"1234\"],\"private_networking\":\"false\",\"backups_enabled\":\"false\",\"ipv6\":null,\"user_data\":null}",
51
91
  :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'}).
52
92
  to_return(:status => 200, :body => fixture('create_droplet'), :headers => {})
53
93
 
@@ -34,6 +34,7 @@ Try creating one with \e[32m`tugboat create`\e[0m
34
34
 
35
35
  expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
36
36
  end
37
+
37
38
  it "shows no output when --quiet is set" do
38
39
  stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
39
40
  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'}).
@@ -47,6 +48,23 @@ Try creating one with \e[32m`tugboat create`\e[0m
47
48
 
48
49
  expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
49
50
  end
51
+
52
+ it "includes urls when --include-urls is set" do
53
+ stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
54
+ 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'}).
55
+ to_return(:status => 200, :body => fixture("show_droplets"), :headers => {'Content-Type' => 'application/json'},)
56
+
57
+ @cli.options = @cli.options.merge("include_urls" => true)
58
+ @cli.droplets
59
+
60
+ expect($stdout.string).to eq <<-eos
61
+ example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
62
+ example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
63
+ example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
64
+ eos
65
+
66
+ expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
67
+ end
50
68
  end
51
69
 
52
70
  end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ describe "DO_API_TOKEN=foobar" do
7
+ it "verifies with the ENV variable DO_API_TOKEN" do
8
+ stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
9
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'Bearer env_variable', 'Content-Type'=>'application/json', 'User-Agent'=>'Faraday v0.9.2'}).
10
+ to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})
11
+
12
+ allow(ENV).to receive(:[]).with('HOME').and_return('/tmp/fake_home')
13
+ allow(ENV).to receive(:[]).with('DO_API_TOKEN').and_return('env_variable')
14
+ allow(ENV).to receive(:[]).with('http_proxy').and_return(nil)
15
+
16
+ @cli.verify
17
+ expect($stdout.string).to eq "Authentication with DigitalOcean was successful.\n"
18
+ expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
19
+ end
20
+
21
+ it "does not use ENV variable DO_API_TOKEN if empty" do
22
+ stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
23
+ 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'}).
24
+ to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})
25
+
26
+ allow(ENV).to receive(:[]).with('HOME').and_return('/tmp/fake_home')
27
+ allow(ENV).to receive(:[]).with('DO_API_TOKEN').and_return('')
28
+ allow(ENV).to receive(:[]).with('http_proxy').and_return(nil)
29
+
30
+ @cli.verify
31
+ expect($stdout.string).to eq "Authentication with DigitalOcean was successful.\n"
32
+ expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
33
+ end
34
+ end
35
+ end
36
+
@@ -24,13 +24,36 @@ Status: \e[32mactive\e[0m
24
24
  IP4: 104.131.186.241
25
25
  IP6: 2604:A880:0800:0010:0000:0000:031D:2001
26
26
  Region: New York 3 - nyc3
27
- Image: 6918990 - 14.04 x64
27
+ Image: 6918990 - ubuntu-14-04-x64
28
28
  Size: 512MB
29
29
  Backups Active: false
30
30
  eos
31
31
 
32
32
  end
33
33
 
34
+ it "shows a droplet made from a user image" do
35
+ stub_request(:get, "https://api.digitalocean.com/v2/droplets/6918990?per_page=200").
36
+ 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'}).
37
+ to_return(:status => 200, :body => fixture('show_droplet_user_image'), :headers => {})
38
+
39
+ @cli.options = @cli.options.merge(:id => 6918990)
40
+ @cli.info
41
+
42
+ expect($stdout.string).to eq <<-eos
43
+ Droplet id provided. Finding Droplet...done\e[0m, 6918990 (example.com)
44
+
45
+ Name: example.com
46
+ ID: 6918990
47
+ Status: \e[32mactive\e[0m
48
+ IP4: 104.131.186.241
49
+ IP6: 2604:A880:0800:0010:0000:0000:031D:2001
50
+ Region: New York 3 - nyc3
51
+ Image: 36646276 - Super Cool Custom Image
52
+ Size: 512MB
53
+ Backups Active: false
54
+ eos
55
+ end
56
+
34
57
  it "shows a droplet with an id" do
35
58
  stub_request(:get, "https://api.digitalocean.com/v2/droplets/6918990?per_page=200").
36
59
  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'}).
@@ -48,7 +71,7 @@ Status: \e[32mactive\e[0m
48
71
  IP4: 104.131.186.241
49
72
  IP6: 2604:A880:0800:0010:0000:0000:031D:2001
50
73
  Region: New York 3 - nyc3
51
- Image: 6918990 - 14.04 x64
74
+ Image: 6918990 - ubuntu-14-04-x64
52
75
  Size: 512MB
53
76
  Backups Active: false
54
77
  eos
@@ -75,7 +98,7 @@ Status: \e[32mactive\e[0m
75
98
  IP4: 104.131.186.241
76
99
  IP6: 2604:A880:0800:0010:0000:0000:031D:2001
77
100
  Region: New York 3 - nyc3
78
- Image: 6918990 - 14.04 x64
101
+ Image: 6918990 - ubuntu-14-04-x64
79
102
  Size: 512MB
80
103
  Backups Active: false
81
104
  eos
@@ -108,7 +131,7 @@ Status: \e[32mactive\e[0m
108
131
  IP4: 104.131.186.241
109
132
  IP6: 2604:A880:0800:0010:0000:0000:031D:2001
110
133
  Region: New York 3 - nyc3
111
- Image: 6918990 - 14.04 x64
134
+ Image: 6918990 - ubuntu-14-04-x64
112
135
  Size: 512MB
113
136
  Backups Active: false
114
137
  eos
@@ -131,7 +154,7 @@ status active
131
154
  ip4 104.131.186.241
132
155
  ip6 2604:A880:0800:0010:0000:0000:031D:2001
133
156
  region nyc3
134
- Image 6918990
157
+ image 6918990
135
158
  size 512mb
136
159
  backups_active false
137
160
  eos
@@ -156,7 +179,7 @@ status active
156
179
  ip4 104.131.186.241
157
180
  ip6 2604:A880:0800:0010:0000:0000:031D:2001
158
181
  region nyc3
159
- Image 6918990
182
+ image 6918990
160
183
  size 512mb
161
184
  backups_active false
162
185
  eos
@@ -212,7 +235,7 @@ Provide one of the following:
212
235
  ip6
213
236
  private_ip
214
237
  region
215
- Image
238
+ image
216
239
  size
217
240
  backups_active
218
241
  eos
@@ -21,6 +21,7 @@ Image fuzzy name provided. Finding image ID...done\e[0m, 12789325 (745.1.0 (alph
21
21
  Name: 745.1.0 (alpha)
22
22
  ID: 12789325
23
23
  Distribution: CoreOS
24
+ Min Disk Size: 20GB
24
25
  eos
25
26
  end
26
27
 
@@ -42,6 +43,7 @@ Image id provided. Finding Image...done\e[0m, 12438838 (Redmine on 14.04)
42
43
  Name: Redmine on 14.04
43
44
  ID: 12438838
44
45
  Distribution: Ubuntu
46
+ Min Disk Size: 20GB
45
47
  eos
46
48
  end
47
49
 
@@ -63,6 +65,7 @@ Image name provided. Finding Image...done\e[0m, 12438838 (Redmine on 14.04)
63
65
  Name: Redmine on 14.04
64
66
  ID: 12438838
65
67
  Distribution: Ubuntu
68
+ Min Disk Size: 20GB
66
69
  eos
67
70
  end
68
71
 
@@ -139,6 +142,7 @@ Please choose a image: ["0", "1", "2", "3", "4", "5", "6", "7"]\x20
139
142
  Name: 14.10 x32
140
143
  ID: 9801951
141
144
  Distribution: Ubuntu
145
+ Min Disk Size: 20GB
142
146
  eos
143
147
  end
144
148
 
@@ -0,0 +1,82 @@
1
+ {
2
+ "droplet": {
3
+ "id": 6918990,
4
+ "name": "example.com",
5
+ "memory": 512,
6
+ "vcpus": 1,
7
+ "disk": 20,
8
+ "locked": false,
9
+ "status": "active",
10
+ "kernel": {
11
+ "id": 2233,
12
+ "name": "Ubuntu 14.04 x64 vmlinuz-3.13.0-37-generic",
13
+ "version": "3.13.0-37-generic"
14
+ },
15
+ "created_at": "2014-11-14T16:36:31Z",
16
+ "features": [
17
+ "ipv6",
18
+ "virtio"
19
+ ],
20
+ "backup_ids": [
21
+
22
+ ],
23
+ "snapshot_ids": [
24
+
25
+ ],
26
+ "image": {
27
+ "id": 36646276,
28
+ "name": "Super Cool Custom Image",
29
+ "distribution": "CentOS",
30
+ "slug": null,
31
+ "public": false,
32
+ "regions": [
33
+ "lon1"
34
+ ],
35
+ "created_at": "2015-02-27T14:44:25Z",
36
+ "min_disk_size": 20,
37
+ "type": "snapshot"
38
+ },
39
+ "size_slug": "512mb",
40
+ "networks": {
41
+ "v4": [
42
+ {
43
+ "ip_address": "104.131.186.241",
44
+ "netmask": "255.255.240.0",
45
+ "gateway": "104.131.176.1",
46
+ "type": "public"
47
+ }
48
+ ],
49
+ "v6": [
50
+ {
51
+ "ip_address": "2604:A880:0800:0010:0000:0000:031D:2001",
52
+ "netmask": 64,
53
+ "gateway": "2604:A880:0800:0010:0000:0000:0000:0001",
54
+ "type": "public"
55
+ }
56
+ ]
57
+ },
58
+ "region": {
59
+ "name": "New York 3",
60
+ "slug": "nyc3",
61
+ "sizes": [
62
+ "32gb",
63
+ "16gb",
64
+ "2gb",
65
+ "1gb",
66
+ "4gb",
67
+ "8gb",
68
+ "512mb",
69
+ "64gb",
70
+ "48gb"
71
+ ],
72
+ "features": [
73
+ "virtio",
74
+ "private_networking",
75
+ "backups",
76
+ "ipv6",
77
+ "metadata"
78
+ ],
79
+ "available": true
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ echo "Hello world"
@@ -6,6 +6,10 @@ describe Tugboat::Middleware::FindDroplet do
6
6
  describe ".call" do
7
7
  it "raises SystemExit with no droplet data" do
8
8
  expect {described_class.new(app).call(env) }.to raise_error(SystemExit)
9
+
10
+ expect($stdout.string).to include 'Tugboat attempted to find a droplet with no arguments'
11
+ expect($stdout.string).to include 'For more help run: '
12
+ expect($stdout.string).to include 'Try running `tugboat '
9
13
  end
10
14
  end
11
15
 
@@ -6,6 +6,10 @@ describe Tugboat::Middleware::FindImage do
6
6
  describe ".call" do
7
7
  it "raises SystemExit with no image data" do
8
8
  expect {described_class.new(app).call(env) }.to raise_error(SystemExit)
9
+
10
+ expect($stdout.string).to include 'Tugboat attempted to find an image with no arguments'
11
+ expect($stdout.string).to include 'For more help run: '
12
+ expect($stdout.string).to include 'Try running `tugboat '
9
13
  end
10
14
  end
11
15
 
@@ -83,7 +83,7 @@ describe Tugboat::Middleware::SSHDroplet do
83
83
  expect {described_class.new(app).call(env)}.to raise_error(SystemExit)
84
84
 
85
85
  expect($stdout.string).to eq <<-eos
86
- Executing SSH ...
86
+ Executing SSH on Droplet ...
87
87
  You asked to ssh to the private IP, but no Private IP found!
88
88
  eos
89
89
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tugboat
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.RC1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Pearkes
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-10-20 00:00:00.000000000 Z
13
+ date: 2015-11-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: thor
@@ -234,6 +234,7 @@ files:
234
234
  - spec/cli/destroy_cli_spec.rb
235
235
  - spec/cli/destroy_image_cli_spec.rb
236
236
  - spec/cli/droplets_cli_spec.rb
237
+ - spec/cli/env_variable_spec.rb
237
238
  - spec/cli/halt_cli_spec.rb
238
239
  - spec/cli/help_cli_spec.rb
239
240
  - spec/cli/images_cli_spec.rb
@@ -266,6 +267,7 @@ files:
266
267
  - spec/fixtures/show_coreos_image.json
267
268
  - spec/fixtures/show_droplet.json
268
269
  - spec/fixtures/show_droplet_inactive.json
270
+ - spec/fixtures/show_droplet_user_image.json
269
271
  - spec/fixtures/show_droplets.json
270
272
  - spec/fixtures/show_droplets_empty.json
271
273
  - spec/fixtures/show_image.json
@@ -279,6 +281,7 @@ files:
279
281
  - spec/fixtures/shutdown_response.json
280
282
  - spec/fixtures/snapshot_response.json
281
283
  - spec/fixtures/ubuntu_image_9801951.json
284
+ - spec/fixtures/user_data.sh
282
285
  - spec/middleware/base_spec.rb
283
286
  - spec/middleware/check_configuration_spec.rb
284
287
  - spec/middleware/check_credentials_spec.rb
@@ -307,9 +310,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
307
310
  version: 1.9.2
308
311
  required_rubygems_version: !ruby/object:Gem::Requirement
309
312
  requirements:
310
- - - ">"
313
+ - - ">="
311
314
  - !ruby/object:Gem::Version
312
- version: 1.3.1
315
+ version: '0'
313
316
  requirements: []
314
317
  rubyforge_project:
315
318
  rubygems_version: 2.4.8
@@ -328,6 +331,7 @@ test_files:
328
331
  - spec/cli/destroy_cli_spec.rb
329
332
  - spec/cli/destroy_image_cli_spec.rb
330
333
  - spec/cli/droplets_cli_spec.rb
334
+ - spec/cli/env_variable_spec.rb
331
335
  - spec/cli/halt_cli_spec.rb
332
336
  - spec/cli/help_cli_spec.rb
333
337
  - spec/cli/images_cli_spec.rb
@@ -360,6 +364,7 @@ test_files:
360
364
  - spec/fixtures/show_coreos_image.json
361
365
  - spec/fixtures/show_droplet.json
362
366
  - spec/fixtures/show_droplet_inactive.json
367
+ - spec/fixtures/show_droplet_user_image.json
363
368
  - spec/fixtures/show_droplets.json
364
369
  - spec/fixtures/show_droplets_empty.json
365
370
  - spec/fixtures/show_image.json
@@ -373,6 +378,7 @@ test_files:
373
378
  - spec/fixtures/shutdown_response.json
374
379
  - spec/fixtures/snapshot_response.json
375
380
  - spec/fixtures/ubuntu_image_9801951.json
381
+ - spec/fixtures/user_data.sh
376
382
  - spec/middleware/base_spec.rb
377
383
  - spec/middleware/check_configuration_spec.rb
378
384
  - spec/middleware/check_credentials_spec.rb