tugboat 2.0.0.RC1 → 2.0.0

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