Skip to content

Commit

Permalink
Change listing droplets to use DropletKit
Browse files Browse the repository at this point in the history
* Changes to use droplet_kit over Barge
* droplet_kit self-paginates, so does not require
Logic for checking pagination. 
* Adds logic for catching errors returned from 
DropletKit, as it doesn’t have a `success?` method
  • Loading branch information
petems committed Nov 21, 2017
1 parent ab41529 commit e6564b9
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 52 deletions.
8 changes: 7 additions & 1 deletion lib/tugboat/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,17 @@ def verify
default: false,
aliases: '-i',
desc: 'Include URLs for the droplets (can be opened in a browser)'
method_option 'per_page',
type: :boolean,
default: 20,
aliases: '-p',
desc: 'Chose how many results to fetch from the DigitalOcean API (larger is slower)'
desc 'droplets [OPTIONS]', 'Retrieve a list of your droplets'
def droplets
Middleware.sequence_list_droplets.call('tugboat_action' => __method__,
'user_quiet' => options[:quiet],
'include_urls' => options['include_urls'])
'include_urls' => options['include_urls'],
'per_page' => options['per_page'],)
end

desc 'images [OPTIONS]', 'Retrieve a list of images'
Expand Down
37 changes: 19 additions & 18 deletions lib/tugboat/middleware/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,29 @@ def call(env)

def verify_credentials(ocean, say_success = false)
begin
response = ocean.droplet.all(per_page: '1', page: '1')
if ocean.is_a?(DropletKit::Client)
response = ocean.droplets.all(per_page: '1', page: '1')

begin
response.first
rescue DropletKit::Error => e
say "Failed to connect to DigitalOcean. Reason given from API:\n#{e}", :red
exit 1
end
else
response = ocean.droplet.all(per_page: '1', page: '1')

unless response.success?
say "Failed to connect to DigitalOcean. Reason given from API: #{response.id} - #{response.message}", :red
exit 1
end
end
rescue Faraday::ClientError => e
say 'Authentication with DigitalOcean failed at an early stage'
say "Error was: #{e}"
exit 1
end

unless response.success?
say "Failed to connect to DigitalOcean. Reason given from API: #{response.id} - #{response.message}", :red
exit 1
end

say 'Authentication with DigitalOcean was successful.', :green if say_success
end

Expand Down Expand Up @@ -80,19 +91,9 @@ def restart_droplet(hard_restart, ocean, droplet_id = '', droplet_name = '')
end

# Get all pages of droplets
def get_droplet_list(ocean)
def get_droplet_list(ocean, per_page = 20)
verify_credentials(ocean)

page = ocean.droplet.all(per_page: 200, page: 1)
return page.droplets unless page.paginated?

Enumerator.new do |enum|
page.droplets.each { |drop| enum.yield drop }
for page_num in 2..page.last_page
page = ocean.droplet.all(per_page: 200, page: page_num)
page.droplets.each { |drop| enum.yield drop }
end
end
pages = ocean.droplets.all(per_page: per_page)
end
end
end
Expand Down
5 changes: 3 additions & 2 deletions lib/tugboat/middleware/list_droplets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ module Middleware
# Check if the client has set-up configuration yet.
class ListDroplets < Base
def call(env)
ocean = env['barge']
ocean = env['droplet_kit']

verify_credentials(ocean)

droplet_list = get_droplet_list ocean
droplet_list = get_droplet_list(ocean, env['per_page'])

has_one = false

droplet_list.each do |droplet|
has_one = true

Expand Down
4 changes: 2 additions & 2 deletions spec/cli/debug_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

Expand All @@ -43,7 +43,7 @@
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

Expand Down
72 changes: 49 additions & 23 deletions spec/cli/droplets_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: { 'Content-Type' => 'application/json' })

Expand All @@ -21,15 +21,16 @@

expect { cli.droplets }.to output(expected_string).to_stdout

expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
end

it 'shows a private IP if droplet in list has private IP' do
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
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' }).
to_return(status: 200, body: fixture('show_droplets_private_ip'), headers: { 'Content-Type' => 'application/json' })

Expand All @@ -41,15 +42,16 @@

expect { cli.droplets }.to output(expected_string).to_stdout

expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
end

it 'returns an error message when no droplets exist' do
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
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' }).
to_return(status: 200, body: fixture('show_droplets_empty'), headers: { 'Content-Type' => 'application/json' })

Expand All @@ -60,30 +62,32 @@

expect { cli.droplets }.to output(expected_string).to_stdout

expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
end

it 'shows no output when --quiet is set' do
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: { 'Content-Type' => 'application/json' })

cli.options = cli.options.merge(quiet: true)
expect { cli.droplets }.not_to output.to_stderr

expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
end

it 'includes urls when --include-urls is set' do
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: { 'Content-Type' => 'application/json' })

Expand All @@ -97,35 +101,57 @@

expect { cli.droplets }.to output(expected_string).to_stdout

expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
end

it 'paginates when multiple pages are returned' do
it 'allows specifying per_page' do
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
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' }).
to_return(status: 200, body: fixture('show_droplets'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=3').
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' }).
to_return(status: 200, body: fixture('show_droplets_paginated_first'), headers: { 'Content-Type' => 'application/json' })
to_return(status: 200, body: fixture('show_droplets_paginated_first'), headers: {})

stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=2&per_page=200').
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=2&per_page=3').
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' }).
to_return(status: 200, body: fixture('show_droplets_paginated_last'), headers: { 'Content-Type' => 'application/json' })

expected_string = <<-eos
page1example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
page1example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
page1example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
page2example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
page2example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
page2example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
cli.options = cli.options.merge('per_page' => '3')

expected_string = <<-eos
page1example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990)
page1example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956)
page1example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444)
page2example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990)
page2example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956)
page2example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444)
eos

cli.options = cli.options.merge('include_urls' => true)
expect { cli.droplets }.to output(expected_string).to_stdout

expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=3')).to have_been_made
expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=2&per_page=3')).to have_been_made
end

it 'shows error on failure in initial stage' do
stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
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' }).
to_return(headers: { 'Content-Type' => 'text/html' }, status: 401, body: fixture('401'))

expected_string = <<-eos
Failed to connect to DigitalOcean. Reason given from API:
401: {
\"id\": \"unauthorized\",
\"message\": \"Unable to authenticate you.\"
}
eos

expect { cli.droplets }.to raise_error(SystemExit).and output(expected_string).to_stdout

expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.once
end

end
end
8 changes: 4 additions & 4 deletions spec/fixtures/show_droplets_paginated_first.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
"available": null
}
},
{
{
"id": 3164444,
"name": "page1example3.com",
"memory": 512,
Expand Down Expand Up @@ -246,11 +246,11 @@
],
"links": {
"pages": {
"last": "https://api.digitalocean.com/v2/droplets?page=2&per_page=1",
"next": "https://api.digitalocean.com/v2/droplets?page=2&per_page=1"
"last": "https://api.digitalocean.com/v2/droplets?page=1&per_page=3",
"next": "https://api.digitalocean.com/v2/droplets?page=2&per_page=3"
}
},
"meta": {
"total": 4
}
}
}
7 changes: 5 additions & 2 deletions spec/fixtures/show_droplets_paginated_last.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,12 @@
}
],
"links": {

"pages": {
"last": "https://api.digitalocean.com/v2/droplets?page=2&per_page=3",
"next": "https://api.digitalocean.com/v2/droplets?page=2&per_page=3"
}
},
"meta": {
"total": 4
}
}
}

0 comments on commit e6564b9

Please sign in to comment.