Code Monkey home page Code Monkey logo

tugboat's Introduction

Tugboat

Build Status Coverage Status

A command line tool for interacting with your DigitalOcean droplets.

History

When Tugboat was created, DigitalOcean was an extremely new cloud provider. They'd only released their public beta back in 2012, and their new SSD backed machines only premiered in early 2013.

Tugboat started out life around that time, back in April 2013. Back then, there were no official libraries for DigitalOcean, and the 1.0 API was a bit unstable and occasionally flakey.

Since then, DigitalOcean has expanded rapidly and has started offering official libraries.

They now have an offically maintained command-line client called doctl.

Some people have asked, where does that leave Tugboat?

If you want the bleeding edge of new features and official support from DigitalOcean engineers, Doctl is the way to go. However, as long as there is one other user out there who likes Tugboat and it's workflow, I will try my darndest to maintain this project, investigate bugs, implement new features and merge pull-requests.

Installation

gem install tugboat

Please note that Tugboat version 0.2.0 and up requires Ruby 1.9 or higher.

Configuration

Run the configuration utility, tugboat authorize. You can grab your keys here.

$ tugboat authorize
Enter your client key: foo
Enter your API key: bar
Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa):
Enter your SSH user (optional, defaults to jack):
Enter your SSH port number (optional, defaults to 22):

To retrieve region, image, size and key ID's, you can use the corresponding tugboat command, such as `tugboat images`.
Defaults can be changed at any time in your ~/.tugboat configuration file.

Enter your default region ID (optional, defaults to 1 (New York)):
Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)):
Enter your default size ID (optional, defaults to 66 (512MB)):
Enter your default ssh key IDs (optional, defaults to '', comma separated string):

Authentication with DigitalOcean was successful!

This will create a .tugboat file in your home folder (eg. ~/.tugboat).

Tugboat will look for a .tugboat config file first in the current directory you're running it in, then will look for one in the home directory.

An example of a .tugboat file:

---
authentication:
  access_token: f8sazukxeh729ggxh9gjavvzw5cabdpq95txpzhz6ep6jvtquxztfkf2chyejcsg5
ssh:
  ssh_user: root
  ssh_key_path: "~/.ssh/id_rsa"
  ssh_port: '22'
defaults:
  region: nyc2
  image: ubuntu-14-04-x64
  size: 512mb
  ssh_key: ['1234','5678']
  private_networking: 'false'
  backups_enabled: 'false'
  ip6: 'false'

Usage

Retrieve a list of your droplets

$ tugboat droplets
pearkes-web-001 (ip: 30.30.30.1, status: active, region: nyc2, id: 13231511)
pearkes-admin-001 (ip: 30.30.30.3, status: active, region: nyc2, id: 13231512)
pearkes-api-001 (ip: 30.30.30.5, status: active, region: nyc2, id: 13231513)

If you wish to use the droplet listing as part of scripting or munging output, you can use the --porcelain:

$ tugboat droplets --attribute=ip4
pearkes-web-001,30.30.30.1
pearkes-admin-001,30.30.30.3
pearkes-api-001,30.30.30.5

Or --attribute parameter:

$ tugboat droplets --porcelain
name pearkes-web-001
id 13231515
status active
ip4 330.30.30.1
region lon1
image 6918990
size 1gb
backups_active false

name pearkes-admin-001
id 13231513
status active
ip4 30.30.30.3
region lon1
image 6918990
size 1gb
backups_active false

name pearkes-web-001
id 13231514
status active
ip4 30.30.30.5
region lon1
image 6918990
size 1gb
backups_active true

Fuzzy name matching

You can pass a unique fragment of a droplets name for interactions throughout tugboat.

$ tugboat restart admin
Droplet fuzzy name provided. Finding droplet ID...done, 13231512 (pearkes-admin-001)
Queuing restart for 13231512 (pearkes-admin-001)...done

tugboat handles multiple matches as well:

$ tugboat restart pearkes
Droplet fuzzy name provided. Finding droplet ID...Multiple droplets found.

0) pearkes-web-001  (13231511)
1) pearkes-admin-001 (13231512)
2) pearkes-api-001 (13231513)

Please choose a droplet: ["0", "1", "2"] 0
Queuing restart for 13231511 (pearkes-web-001)...done

SSH into a droplet

You can configure an SSH username and key path in tugboat authorize, or by changing your ~/.tugboat.

This lets you ssh into a droplet by providing it's name, or a partial match.

$ tugboat ssh admin
Droplet fuzzy name provided. Finding droplet ID...done, 13231512 (pearkes-admin-001)
Executing SSH (pearkes-admin-001)...
Welcome to Ubuntu 12.10 (GNU/Linux 3.5.0-17-generic x86_64)
pearkes@pearkes-admin-001:~#

SCP files to droplet

You can configure an SSH username and key path in tugboat authorize, or by changing your ~/.tugboat.

This lets you scp a file into a droplet by providing it's name, or a partial match.

$ tugboat scp test-scp /tmp/foo /tmp/bar
Droplet fuzzy name provided. Finding droplet ID...done, 72025053 (test-scp)
Executing SCP on Droplet (test-scp)...
Attempting SCP with `scp -i /Users/petems/.ssh/digital_ocean /tmp/foo [email protected]:/tmp/bar`
foo
                                              100%    0     0.0KB/s   00:00

Create a droplet

$ tugboat create pearkes-www-002 -s 512mb -i ubuntu-12-04-x64 -r nyc2 -k 11251
Queueing creation of droplet 'pearkes-www-002'...done

Info about a droplet

$ tugboat info admin
Droplet fuzzy name provided. Finding droplet ID...done, 13231512 (pearkes-admin-001)

Name:             pearkes-admin-001
ID:               13231512
Status:           active
IP:               30.30.30.3
Backups Active:   false
IP6:              2A03:B0C0:0001:00D0:0000:0000:0308:D001
Region:           London 1 - lon1
Image:            6918990 - ubuntu-14-04-x64
Size:             1GB

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.

$ tugboat info -n pearkes-admin-001 --porcelain
name pearkes-admin-001
id 13231512
status active
ip4 30.30.30.3
region lon1
image 6918990
size 1gb
backups_active false

Print a single attribute.

$ tugboat info -n pearkes-admin-001 --attribute ip --porcelain
30.30.30.3

Destroy a droplet

$ tugboat destroy pearkes-www-002
Droplet fuzzy name provided. Finding droplet ID...done, 13231515 (pearkes-www-002)
Warning! Potentially destructive action. Please confirm [y/n]: y
Queuing destroy for 13231515 (pearkes-www-002)...done

Restart a droplet

$ tugboat restart admin
Droplet fuzzy name provided. Finding droplet ID...done, 13231512 (pearkes-admin-001)
Queuing restart for 13231512 (pearkes-admin-001)...done

Shutdown a droplet

$ tugboat halt admin
Droplet fuzzy name provided. Finding droplet ID...done, 13231512 (pearkes-admin-001)
Queuing shutdown for 13231512 (pearkes-admin-001)...done

Snapshot a droplet

$ tugboat snapshot test-admin-snaphot admin
Queuing snapshot 'test-admin-snapshot' for 13231512 (pearkes-admin-001)...done

Resize a droplet

$ tugboat resize admin -s 66
Queuing resize for 13231512 (pearkes-admin-001)...done

Enabling backups on a droplet

$ tugboat backup_config admin --on
Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 6918990 (example.com)
Backup action enable backups is complete

Disabling backups on a droplet

$ tugboat backup_config admin --off
Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 6918990 (example.com)
Backup action disable backups is complete

List Available Images

You can list all images

$ tugboat images
Showing both private and public images
Private Images:
My application image (id: 6376601, distro: Ubuntu)

Public Images:
745.1.0 (alpha) (slug: coreos-alpha, id: 12789325, distro: CoreOS)
723.3.0 (beta) (slug: coreos-beta, id: 12789350, distro: CoreOS)
717.3.0 (stable) (slug: coreos-stable, id: 12789351, distro: CoreOS)
....

Or just list images that you have created.

$ tugboat images --show_just_private_images # or -p
Showing just private images
Private Images:
My application image (id: 6376601, distro: Ubuntu)
....

List Current Snapshots

$ tugboat snapshots
code-freeze-backup-october (id: 2013184, resource_type: droplet, created_at: 2016-10-06T11:43:06Z)
test-admin 2017-05-31 (id: 20234485, resource_type: droplet, created_at: 2017-05-31T02:07:07Z)
test-admin 2017-11-08 (id: 21133567, resource_type: droplet, created_at: 2017-11-08T02:49:09Z)
test-admin 2017-11-15 (id: 22355454, resource_type: droplet, created_at: 2017-11-15T03:11:08Z)
test-admin 2017-11-22 (id: 24523423, resource_type: droplet, created_at: 2017-11-22T03:10:09Z)
test-admin 2017-11-29 (id: 26212345, resource_type: droplet, created_at: 2017-11-29T03:15:25Z)
....

List Available Sizes

$ tugboat sizes
Sizes:
Disk: 20GB, Memory: 512MB (slug: 512mb)
Disk: 30GB, Memory: 1024MB (slug: 1gb)
Disk: 40GB, Memory: 2048MB (slug: 2gb)
Disk: 60GB, Memory: 4096MB (slug: 4gb)
Disk: 80GB, Memory: 8192MB (slug: 8gb)
Disk: 160GB, Memory: 16384MB (slug: 16gb)
Disk: 320GB, Memory: 32768MB (slug: 32gb)
Disk: 480GB, Memory: 49152MB (slug: 48gb)
Disk: 640GB, Memory: 65536MB (slug: 64gb)
...

List Available Regions

$ tugboat regions
Regions:
Amsterdam 1 (slug: ams1)
Amsterdam 2 (slug: ams2)
Amsterdam 3 (slug: ams3)
London 1 (slug: lon1)
New York 1 (slug: nyc1)
New York 2 (slug: nyc2)
New York 3 (slug: nyc3)
San Francisco 1 (slug: sfo1)
Singapore 1 (slug: sgp1)

Add SSH keys

$ tugboat add-key digitalocean
Possible public key paths from /Users/pearkes/.ssh:

/Users/pearkes/.ssh/digitalocean.pub
/Users/pearkes/.ssh/fog.pub
/Users/pearkes/.ssh/github.pub
/Users/pearkes/.ssh/id_rsa.pub
/Users/pearkes/.ssh/terraform.pub

Enter the path to your SSH key: /Users/petersouter/.ssh/digitalocean.pub
Queueing upload of SSH key 'digitalocean'...SSH Key uploaded

Name: digitalocean
ID: 1384812
...

List SSH Keys

$ tugboat keys
Keys:
Name: pearkes, (id: 231192), fingerprint: 3b:16:bf:e4:8b:00:8b:b8:59:8c:a9:d3:f0:19:45:fa
...

Wait for Droplet State

Sometimes you want to wait for a droplet to enter some state, for example "off".

$ tugboat wait admin --state off
Droplet fuzzy name provided. Finding droplet ID...done, 13231512 (pearkes-admin-001)
Waiting for droplet to become off....
...

This will simply block until the droplet returns a state of "off". A period will be printed after each request.

Help

If you're curious about command flags for a specific command, you can ask tugboat about it.

$ tugboat help restart

For a complete overview of all of the available commands, run:

$ tugboat help

Depending on your local configuration, you may need to install a CA bundle (OS X only) using homebrew to communicate with DigitalOcean through SSL/TLS:

$ brew install curl-ca-bundle

After installation, source the bundle path in your .bash_profile/.bashrc:

export SSL_CERT_FILE=/usr/local/opt/curl-ca-bundle/share/ca-bundle.crt

Reporting Bugs

Yes, please!

You can create a new issue here. To help with the investigation of your issue, you can set the environment variable DEBUG to give verbose Faraday logging.

  • DEBUG=1 is full unredacted
  • DEBUG=2 redacts private keys from the log.

Example:

DEBUG=2 bundle exec tugboat regions
I, [2015-12-06T12:04:27.148922 #92772]  INFO -- : Started GET request to: https://api.digitalocean.com/v2/regions?per_page=200
D, [2015-12-06T12:04:27.149334 #92772] DEBUG -- : Request Headers:
----------------
Authorization : Bearer [TOKEN REDACTED]
Content-Type  : application/json
User-Agent    : Faraday v0.9.2

Request Body:
-------------
{
  "regions": [
    {
      "name": "New York 1",
      "slug": "nyc1",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "Amsterdam 1",
      "slug": "ams1",
      "sizes": [
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb"
      ],
      "features": [
        "backups"
      ],
      "available": true
    },
    {
      "name": "San Francisco 1",
      "slug": "sfo1",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "New York 2",
      "slug": "nyc2",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "Amsterdam 2",
      "slug": "ams2",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "Singapore 1",
      "slug": "sgp1",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "London 1",
      "slug": "lon1",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "New York 3",
      "slug": "nyc3",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "Amsterdam 3",
      "slug": "ams3",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "Frankfurt 1",
      "slug": "fra1",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    },
    {
      "name": "Toronto 1",
      "slug": "tor1",
      "sizes": [
        "32gb",
        "16gb",
        "2gb",
        "1gb",
        "4gb",
        "8gb",
        "512mb",
        "64gb",
        "48gb"
      ],
      "features": [
        "private_networking",
        "backups",
        "ipv6",
        "metadata"
      ],
      "available": true
    }
  ],
  "links": {
  },
  "meta": {
    "total": 11
  }
}

Contributing

See the contributing guide.

tugboat's People

Contributors

andrehjr avatar blakelapierre avatar blom avatar bmamlin avatar brandondrew avatar calebreach avatar dalemyers avatar elliotthilaire avatar elsbrock avatar ethanal avatar ferada avatar freedomben avatar jamshedvesuna avatar jasnow avatar lachesis avatar mtbottle avatar obradovic avatar pchaussalet avatar pearkes avatar petems avatar philetaylor avatar ream88 avatar seanhussey avatar seeekr avatar simi avatar spearway avatar tggo avatar wadtech avatar wietsewind avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tugboat's Issues

Enable Private Networking

Might it be possible to enable private networking when creating a droplet from a snapshot using tugboat?

"undefined method `each' for nil:NilClass" in every endpoint

A strange bit is that I was able to run tugboat sizes once after authorizing, and it worked. However, every request using tugboat since that has failed. Example stacktrace:

~ % tugboat droplets                                                                                                                 2.0.0-p247
/Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/middleware/list_droplets.rb:8:in `call': undefined method `each' for nil:NilClass (NoMethodError)
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/middleware/inject_client.rb:14:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/middleware/check_configuration.rb:13:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/middleware/inject_configuration.rb:10:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/middleware-0.1.0/lib/middleware/runner.rb:31:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/middleware-0.1.0/lib/middleware/builder.rb:102:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/cli.rb:41:in `droplets'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/bin/tugboat:10:in `<top (required)>'
    from /Users/david/.rbenv/versions/2.0.0-p247/bin/tugboat:23:in `load'
    from /Users/david/.rbenv/versions/2.0.0-p247/bin/tugboat:23:in `<main>'

Almost every stacktrace looks the same; every endpoint that lists something is affected for me. If the endpoint is supposed to do something with a single droplet, the undefined method is instead each_with_index. e.g:

~ % tugboat info tomato                                                                                                              2.0.0-p247
Droplet fuzzy name provided. Finding droplet ID.../Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/middleware/find_droplet.rb:73:in `call': undefined method `each_with_index' for nil:NilClass (NoMethodError)
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/middleware/inject_client.rb:14:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/middleware/check_configuration.rb:13:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/middleware/inject_configuration.rb:10:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/middleware-0.1.0/lib/middleware/runner.rb:31:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/middleware-0.1.0/lib/middleware/builder.rb:102:in `call'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/lib/tugboat/cli.rb:194:in `info'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /Users/david/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/tugboat-0.0.6/bin/tugboat:10:in `<top (required)>'
    from /Users/david/.rbenv/versions/2.0.0-p247/bin/tugboat:23:in `load'
    from /Users/david/.rbenv/versions/2.0.0-p247/bin/tugboat:23:in `<main>'

Supporting MRI 1.8.7

What do you think about supporting MRI 1.8.7, and testing against it on Travis? The tests already pass on 1.8.7. It is EOL in June and all, but plenty of people will use it for some time to come. We would just need to do something about the debugger development dependency as it won't install on < 1.9.2. We could remove it from the gemspec, or move it to the Gemfile and use :platforms.

Smart group my droplets

Planning to make droplets list more clear, currently (if #77 gets merged) , supposing 2 projects, multiple servers you'll end up with something like:

ON   foo-db1              16.213.17.111    @ New York 2      #123456
ON   foo-web1             16.213.17.111    @ New York 2      #123456
ON   bar-db1              16.213.17.111    @ New York 2      #123456
ON   bar-web1             16.213.17.111    @ New York 2      #123456
....

I propose a split and group with '-' hifens:

bar
    ON   db1.foo.com               16.213.17.111    @ New York 2      #123456
    ON   web1.foo.com              16.213.17.111    @  New York 2      #123456
foo
    ON   db1.foo.com               16.213.17.111    @ New York 2      #123456
    ON   web1.foo.com              16.213.17.111    @  New York 2      #123456
    ....

Kinda like linode groups. We could also do actions on groups, like god (monit).
You may not provide any hifen, so the listing will be the same. Also, maybe a option to don't group.
Any ideas?

pass through ssh commands

WOuld it be possible to pass through commands to ssh when using tugboat ssh "ls" such that "ls" would gets passed through to ssh to be executed on the remote machine? This would aid significantly in using tugboat in scripting.

Also, I love this tool. Just sayin.

Add a --quiet option

A --quiet global option would be useful, with result being returned by exit code.

This would be another solution to #85

Add ability to set default region

Add a field into .tugboat that gives a default region when doing a droplet creation, so when you create a droplet it will use that value by default.

cli.rb:175: syntax error, unexpected ')', expecting '=' (SyntaxError)

Here is my complete (short) journey with tugboat that came to a very quick and immediate end :-(

sudo gem install tugboat
Password:
Building native extensions. This could take a while...
Successfully installed thor-0.18.1
Successfully installed multipart-post-1.2.0
Successfully installed faraday-0.8.7
Successfully installed faraday_middleware-0.9.0
Successfully installed json-1.7.7
Successfully installed hashie-2.0.3
Successfully installed rash-0.4.0
Successfully installed digital_ocean-1.0.1
Successfully installed middleware-0.1.0
Successfully installed tugboat-0.0.3
10 gems installed
Installing ri documentation for thor-0.18.1...
Installing ri documentation for multipart-post-1.2.0...
Installing ri documentation for faraday-0.8.7...
Installing ri documentation for faraday_middleware-0.9.0...
Installing ri documentation for json-1.7.7...
Installing ri documentation for hashie-2.0.3...
Installing ri documentation for rash-0.4.0...
Installing ri documentation for digital_ocean-1.0.1...
Installing ri documentation for middleware-0.1.0...
Installing ri documentation for tugboat-0.0.3...
Installing RDoc documentation for thor-0.18.1...
Installing RDoc documentation for multipart-post-1.2.0...
Installing RDoc documentation for faraday-0.8.7...
Installing RDoc documentation for faraday_middleware-0.9.0...
Installing RDoc documentation for json-1.7.7...
Installing RDoc documentation for hashie-2.0.3...
Installing RDoc documentation for rash-0.4.0...
Installing RDoc documentation for digital_ocean-1.0.1...
Installing RDoc documentation for middleware-0.1.0...
Installing RDoc documentation for tugboat-0.0.3...
phils-imac-2012:~ phil$ tugboat authorize
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in gem_original_require': /Library/Ruby/Gems/1.8/gems/tugboat-0.0.3/lib/tugboat/cli.rb:175: syntax error, unexpected ')', expecting '=' (SyntaxError) /Library/Ruby/Gems/1.8/gems/tugboat-0.0.3/lib/tugboat/cli.rb:184: syntax error, unexpected kEND, expecting $end from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:inrequire'
from /Library/Ruby/Gems/1.8/gems/tugboat-0.0.3/lib/tugboat.rb:1
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in gem_original_require' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:inrequire'
from /Library/Ruby/Gems/1.8/gems/tugboat-0.0.3/bin/tugboat:2
from /usr/bin/tugboat:19:in `load'
from /usr/bin/tugboat:19

Add SSH key to account

Something like tugboat keys add ~/.ssh/awesome_key.pub

From the API

Add SSH Key
This method allows you to add a new public SSH key to your account.

Request URL:
https://api.digitalocean.com/ssh_keys/new/?name=[ssh_key_name]&ssh_pub_key=[ssh_public_key]client_id=[your_client_id]&api_key=[your_api_key]
Parameters
name Required, String, the name you want to give this SSH key.
ssh_key_pub Required, String, the actual public SSH key.
Sample Response
{
  "status": "OK",
  "ssh_key": {
    "id": 47,
    "name": "my_key",
    "ssh_pub_key": "ssh-dss AAAAB3NzaC1kc3MAAACBAK5uLwicCrFEpaVKBzkWxC7RQn+smg5ZQb5keh9RQKo8AszFTol5npgUAr0JWmqKIHv7nof0HndO86x9iIqNjq3vrz9CIVcFfZM7poKBJZ27Hv3v0fmSKfAc6eGdx8eM9UkZe1gzcLXK8UP2HaeY1Y4LlaHXS5tPi/dXooFVgiA7AAAAFQCQl6LZo/VYB9VgPEZzOmsmQevnswAAAIBCNKGsVP5eZ+IJklXheUyzyuL75i04OOtEGW6MO5TymKMwTZlU9r4ukuwxty+T9Ot2LqlNRnLSPQUjb0vplasZ8Ix45JOpRbuSvPovryn7rvS7//klu9hIkFAAQ/AZfGTw+696EjFBg4F5tN6MGMA6KrTQVLXeuYcZeRXwE5t5lwAAAIEAl2xYh098bozJUANQ82DiZznjHc5FW76Xm1apEqsZtVRFuh3V9nc7QNcBekhmHp5Z0sHthXCm1XqnFbkRCdFlX02NpgtNs7OcKpaJP47N8C+C/Yrf8qK/Wt3fExrL2ZLX5XD2tiotugSkwZJMW5Bv0mtjrNt0Q7P45rZjNNTag2c= user@host"
  }
}

Unable to run tugboat after installing

On a Digital Ocean Ubuntu 12.04 x64 droplet, I get a syntax error when running tugboat. Ruby is 1.8.7, gem is 1.8.15, tugboat is 0.2.0.

The error is: syntax error, unexpected ':', expecting kEND (SyntaxError).

More information below.

ar@ocean:~/ansible$ sudo gem install tugboat
Successfully installed tugboat-0.2.0
1 gem installed
Installing ri documentation for tugboat-0.2.0...
Installing RDoc documentation for tugboat-0.2.0...
ar@ocean:~/ansible$ tugboat
/usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require': /var/lib/gems/1.8/gems/tugboat-0.2.0/lib/tugboat/cli.rb:12: syntax error, unexpected ':', expecting kEND (SyntaxError)
class_option :quiet, type: :boolean, aliases: "-q"
                          ^
from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `require'
from /var/lib/gems/1.8/gems/tugboat-0.2.0/lib/tugboat.rb:1
from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `require'
from /var/lib/gems/1.8/gems/tugboat-0.2.0/bin/tugboat:8
from /usr/local/bin/tugboat:19:in `load'
from /usr/local/bin/tugboat:19
ar@ocean:~/ansible$ ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]
ar@ocean:~/ansible$ gem -v
1.8.15

Scrub API Keys from Logs

We should replace them with something innocuous. As we're just falling back to Faraday's logging, I'm not sure if this is possible or how we might do it.

Droplet migration between datacenters

There is a VM in one DC, e.g. AMS1. I want to migrate it to the NY1.
I want to execute:
tugboat migrate my-droplet --from=2 --to=1
and in a couple of minutes see my droplet active in the desired datacenter.

Destroy data by default...

tl;dr fog/fog#2525

Not sure what the full craic is with this, but we might want to switch to prompting the user if they want to destroy data on the VM's or just doing it by default.

certificate verify failed

With the latest version, from 2 different networks.

Before going tinfoil, did DO change certificate? And big props for doing cert pinning, if that is the case!

(Ah, BTW, SSLv3? ๐Ÿ˜’)

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed!
/usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/middleware/authentication_middleware.rb:24:in `rescue in call': undefined method `status' for nil:NilClass (NoMethodError)
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/middleware/authentication_middleware.rb:20:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/faraday-0.8.9/lib/faraday/connection.rb:253:in `run_request'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/faraday-0.8.9/lib/faraday/connection.rb:106:in `get'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/digital_ocean-1.0.1/lib/digital_ocean/resource/droplet.rb:6:in `list'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/middleware/check_credentials.rb:11:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/middleware/inject_client.rb:33:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/middleware/check_configuration.rb:13:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/middleware/inject_configuration.rb:10:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/middleware/ask_for_credentials.rb:27:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/middleware/inject_configuration.rb:10:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/middleware-0.1.0/lib/middleware/runner.rb:31:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/middleware-0.1.0/lib/middleware/builder.rb:102:in `call'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/lib/tugboat/cli.rb:36:in `authorize'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/gems/2.0.0/gems/tugboat-0.0.9/bin/tugboat:10:in `<top (required)>'
    from /usr/local/opt/ruby/bin/tugboat:23:in `load'
    from /usr/local/opt/ruby/bin/tugboat:23:in `<main>'

Option to manage SSH keys

Hi,

At the moment tugboat is capable of listing the SSH keys, but there is no feature to add, edit and destroy keys. The DO API is able to do these. Could you please implement these features?

Thanks,

David

Error: Faraday::Error::ParsingError n-1.6.7/lib/json/common.rb:149:in `parse': 757

Initially everything worked fine however after a while I am not able to do anything and getting following error with every command.
Using OSX 1.7.5

 (Faraday::Error::ParsingError)n-1.6.7/lib/json/common.rb:149:in `parse': 757: unexpected token at '<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
'
        from /Library/Ruby/Gems/1.8/gems/json-1.6.7/lib/json/common.rb:149:in `parse'
        from /Library/Ruby/Gems/1.8/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response/parse_json.rb:11
        from /Library/Ruby/Gems/1.8/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:48:in `call'
        from /Library/Ruby/Gems/1.8/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:48:in `parse'
        from /Library/Ruby/Gems/1.8/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:39:in `process_response'
        from /Library/Ruby/Gems/1.8/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:32:in `call'
        from /Library/Ruby/Gems/1.8/gems/faraday-0.8.7/lib/faraday/response.rb:63:in `on_complete'
        from /Library/Ruby/Gems/1.8/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:30:in `call'
        from /Library/Ruby/Gems/1.8/gems/faraday-0.8.7/lib/faraday/response.rb:8:in `call'
        from /Library/Ruby/Gems/1.8/gems/faraday-0.8.7/lib/faraday/request/url_encoded.rb:14:in `call'
        from /Library/Ruby/Gems/1.8/gems/digital_ocean-1.0.1/lib/digital_ocean/authentication_middleware.rb:18:in `call'
        from /Library/Ruby/Gems/1.8/gems/faraday-0.8.7/lib/faraday/connection.rb:247:in `run_request'
        from /Library/Ruby/Gems/1.8/gems/faraday-0.8.7/lib/faraday/connection.rb:100:in `get'
        from /Library/Ruby/Gems/1.8/gems/digital_ocean-1.0.1/lib/digital_ocean/resource/droplet.rb:6:in `list'
        from /Library/Ruby/Gems/1.8/gems/tugboat-0.0.5/lib/tugboat/middleware/list_droplets.rb:8:in `call'
        from /Library/Ruby/Gems/1.8/gems/tugboat-0.0.5/lib/tugboat/middleware/inject_client.rb:14:in `call'
        from /Library/Ruby/Gems/1.8/gems/tugboat-0.0.5/lib/tugboat/middleware/check_configuration.rb:13:in `call'
        from /Library/Ruby/Gems/1.8/gems/tugboat-0.0.5/lib/tugboat/middleware/inject_configuration.rb:10:in `call'
        from /Library/Ruby/Gems/1.8/gems/middleware-0.1.0/lib/middleware/runner.rb:31:in `call'
        from /Library/Ruby/Gems/1.8/gems/middleware-0.1.0/lib/middleware/builder.rb:102:in `call'
        from /Library/Ruby/Gems/1.8/gems/tugboat-0.0.5/lib/tugboat/cli.rb:39:in `droplets'
        from /Library/Ruby/Gems/1.8/gems/thor-0.18.1/lib/thor/command.rb:27:in `__send__'
        from /Library/Ruby/Gems/1.8/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
        from /Library/Ruby/Gems/1.8/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
        from /Library/Ruby/Gems/1.8/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
        from /Library/Ruby/Gems/1.8/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
        from /Library/Ruby/Gems/1.8/gems/tugboat-0.0.5/bin/tugboat:10
        from /usr/bin/tugboat:19:in `load'
        from /usr/bin/tugboat:19

Unable to authorise

I'm attempting to authorise but I keep getting this error:

report/latex git:(master) โœ— ยฑ tugboat authorize                                                                                                                                                    19:20:26
Note: You can get this information from digitalocean.com/api_access

Enter your client key: <removed>
Enter your API key: <removed>
Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa):
Enter your SSH user (optional, defaults to mattoakes): <removed>
Authentication with DigitalOcean failed. Run `tugboat authorize`

These values are defiantly correct and have no extra whitespace around them. I've tried installing the gem both as my normal user and also using sudo.

I'm running OS X 10.8.2, ruby 1.9.3p194 and gem 1.8.25. I've verified that I can access Digital Ocean by browsing to the website and pinging the from the command line.

Any ideas what I'm doing wrong?

"Wait" Tool

I think it'd be pretty sweet to have a tool like this:

tugboat wait admin-001 --state active

That would poll the droplet every N seconds and say "ready" or something like that when it gets the state you pass in with -s or --state.

Provide an option to disable color in `droplets` command

While the colorized output of tugboat droplets is nice when visually inspecting the output, it can cause problems when one wants to use the command in scripts (either logging information to a file, or using it to check the status of a droplet).

An option to disable color would be helpful, as would making tugboat behave more like other software that automatically disables color codes when stdout is not attached to a tty.

Problem with SSL certificate

Hi,

I have been using tugboat without any issues for a few weeks now. All of the sudden it stopped working and says:

user@computer:~$ tugboat droplets
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed!
/var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/authentication_middleware.rb:24:in call': undefined methodstatus' for nil:NilClass (NoMethodError)
from /var/lib/gems/1.8/gems/faraday-0.8.8/lib/faraday/connection.rb:253:in run_request' from /var/lib/gems/1.8/gems/faraday-0.8.8/lib/faraday/connection.rb:106:inget'
from /var/lib/gems/1.8/gems/digital_ocean-1.0.1/lib/digital_ocean/resource/droplet.rb:6:in list' from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/list_droplets.rb:8:incall'
from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/inject_client.rb:33:in call' from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/check_configuration.rb:13:incall'
from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/inject_configuration.rb:10:in call' from /var/lib/gems/1.8/gems/middleware-0.1.0/lib/middleware/runner.rb:31:incall'
from /var/lib/gems/1.8/gems/middleware-0.1.0/lib/middleware/builder.rb:102:in call' from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/cli.rb:50:indroplets'
from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor/command.rb:27:in __send__' from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor/command.rb:27:inrun'
from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor/invocation.rb:120:in invoke_command' from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor.rb:363:indispatch'
from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor/base.rb:439:in start' from /var/lib/gems/1.8/gems/tugboat-0.0.8/bin/tugboat:10 from /usr/local/bin/tugboat:19:inload'
from /usr/local/bin/tugboat:19

I have no idea what happened or what changed. It woked a few hours ago and I did not change anything (as far as I can tell).

Thanks,

David

Release 0.0.5

Don't know if we're there yet, but creating this issue to track when the best time to release 0.0.5 is.

Manage DNS records

It would be nice be able to manage DNS records using tugboat too

I am doing a workaround (sorry not good at ruby) right now using:

tugboat create server.domain.tld -i 303619 -r 2 -k 32527
Wait till server becomes active:
tugboat wait server.domain.tld --state active
Get the IP address from
tugboat info "#{SERVER_TO_DEPLOY}" |grep IP|awk {'print $2'}

And then use a curl script (using digital ocean API) to update DNS records.

I forked the repository to see if I can do it by myself but I don't know where to start.
Any tip or idea?

Thanks for your time

Tugboat rename droplet command

Add tugboat rename command

From the API:

Rename Droplet
This method renames the droplet to the specified name.

Request URL:
https://api.digitalocean.com/droplets/[droplet_id]/rename/?client_id=[your_client_id]&api_key=[your_api_key]&name=[name]
Parameters
droplet_id Required, Numeric, this is the id of your droplet that you want to rename
name Required, String, new name of the droplet
Sample Response
{
  "status": "OK",
  "event_id": 7504
}

Machine Readable Flag

A global flag to make the output more machine readable. Currently it's optimized for humans.

Maybe:

--machine-readable

Timeout while executing tugboat wait

Hi

I am having the following error:

tugboat create do6.example.com -i 303619 -r 2 -k 32527
Queueing creation of droplet 'do6.example.com'...done
tugboat wait do6.example.com --state active
Droplet fuzzy name provided. Finding droplet ID...done, 664699 (do6.eltorete.com)
Waiting for droplet to become active.........../usr/lib/ruby/1.9.1/net/http.rb:762:in `initialize': Connection timed out - connect(2) (Errno::ETIMEDOUT)
        from /usr/lib/ruby/1.9.1/net/http.rb:762:in `open'
        from /usr/lib/ruby/1.9.1/net/http.rb:762:in `block in connect'
        from /usr/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
        from /usr/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
        from /usr/lib/ruby/1.9.1/net/http.rb:762:in `connect'
        from /usr/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
        from /usr/lib/ruby/1.9.1/net/http.rb:744:in `start'

It would be very useful if the timeout parameter could be modified on the command line.
tugboat wait do6.example.com --timeout 300 --state active

Thank you

Droplet create with backups enabled.

Recently, DO has changed their backups structure and to have backups enabled in a Droplet, you now have to enable it during the droplet creation.

Since I use backups in all my Droplets, I can't create Droplets using Tugboat anymore :(

Release 0.0.8

I just released version 0.0.8.

Changelog here. In short, we now have default config thanks to @petems!

To set-up defaults on an existing Tugboat installation, run gem install tugboat and then re-run tugboat authorize. You may want to cat ~/.tugboat first so you don't have to go back to DigitalOcean to get your keys.

Handle 401s more gracefully...

Related to #52

We should handle credentials being incorrect/expired in a nicer way. I think we'll have to do this upstream on digital_ocean and then pull in the changes.

We can have some sort of "Catch Faraday 401 error, tell the user to check their credentials and then exit" rather than the default full stacktrace that Faraday provides.

Default image Id no longer exists

The default image id both looks wrong ('350076') and no longer exists in the image list.
It should probably be updated from 13.04 to 14.04.
Ubuntu 14.04 x64 (id: 3240036, distro: Ubuntu)

Cannot destroy droplet

I am unable to destroy a droplet.
After the droplet is found is the confirmation is asked, I hit y and this is what I get.

Droplet fuzzy name provided. Finding droplet ID...done, 532409 (test)
Warning! Potentially destructive action. Please confirm [y/n]: y
Queuing destroy for 532409 (test)...757: unexpected token at '<!DOCTYPE html>
<html>
<head>
  <title>The page you were looking for doesn't exist (404)</title>
  <style>
  body {
    background-color: #EFEFEF;
    color: #2E2F30;
    text-align: center;
    font-family: arial, sans-serif;
  }

  div.dialog {
    width: 25em;
    margin: 4em auto 0 auto;
    border: 1px solid #CCC;
    border-right-color: #999;
    border-left-color: #999;
    border-bottom-color: #BBB;
    border-top: #B00100 solid 4px;
    border-top-left-radius: 9px;
    border-top-right-radius: 9px;
    background-color: white;
    padding: 7px 4em 0 4em;
  }

  h1 {
    font-size: 100%;
    color: #730E15;
    line-height: 1.5em;
  }

  body > p {
    width: 33em;
    margin: 0 auto 1em;
    padding: 1em 0;
    background-color: #F7F7F7;
    border: 1px solid #CCC;
    border-right-color: #999;
    border-bottom-color: #999;
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
    border-top-color: #DADADA;
    color: #666;
    box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
  }
  </style>
</head>

<body>
  <!-- This file lives in public/404.html -->
  <div class="dialog">
    <h1>The page you were looking for doesn't exist.</h1>
    <p>You may have mistyped the address or the page may have moved.</p>
  </div>
  <p>If you are the application owner check the logs for more information.</p>
</body>
</html>
'!
/var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/authentication_middleware.rb:24:in `call': undefined method `status' for #<String:0x7f08d35de9d0> (NoMethodError)
    from /var/lib/gems/1.8/gems/faraday-0.8.8/lib/faraday/connection.rb:253:in `run_request'
    from /var/lib/gems/1.8/gems/faraday-0.8.8/lib/faraday/connection.rb:106:in `delete'
    from /var/lib/gems/1.8/gems/digital_ocean-1.0.1/lib/digital_ocean/resource/droplet.rb:80:in `delete'
    from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/destroy_droplet.rb:9:in `call'
    from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/confirm_action.rb:17:in `call'
    from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/find_droplet.rb:116:in `call'
    from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/inject_client.rb:33:in `call'
    from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/check_configuration.rb:13:in `call'
    from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/middleware/inject_configuration.rb:10:in `call'
    from /var/lib/gems/1.8/gems/middleware-0.1.0/lib/middleware/runner.rb:31:in `call'
    from /var/lib/gems/1.8/gems/middleware-0.1.0/lib/middleware/builder.rb:102:in `call'
    from /var/lib/gems/1.8/gems/tugboat-0.0.8/lib/tugboat/cli.rb:138:in `destroy'
    from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor/command.rb:27:in `__send__'
    from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
    from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
    from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
    from /var/lib/gems/1.8/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /var/lib/gems/1.8/gems/tugboat-0.0.8/bin/tugboat:10
    from /usr/local/bin/tugboat:19:in `load'
    from /usr/local/bin/tugboat:19

Unable to authorize tugboat

I tried to authorize it but I receive the following error

I, [2013-12-06T04:14:35.580345 #6046]  INFO -- : Started GET request to: https://api.digitalocean.com/droplets?client_id=[CLIENT-ID]&api_key=[API-KEY]
D, [2013-12-06T04:14:35.580483 #6046] DEBUG -- : Request Headers:
----------------
User-Agent : Faraday v0.8.8

Request Body:
-------------


uninitialized constant JSON::Parser!
/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/tugboat-0.0.8/lib/tugboat/middleware/authentication_middleware.rb:24:in `rescue in call': undefined method `status' for #<String:0x007f9a33876700> (NoMethodError)

New release?

Maybe it's time for a new release soon? The 0.0.5 gem gives the following error message when an image is not supplied to tugboat create (fixed in #39): You specified an invalid image for Droplet creation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.