Skip to content

Instantly share code, notes, and snippets.

@stephaneliu
Last active August 29, 2015 14:08
Show Gist options
  • Save stephaneliu/d717f5c9d7185ac9d145 to your computer and use it in GitHub Desktop.
Save stephaneliu/d717f5c9d7185ac9d145 to your computer and use it in GitHub Desktop.
Error
#!/usr/bin/env ruby
require 'barge'
require 'delegate'
class DigitalOcean
attr_reader :client, :droplets, :sizes
def initialize
@client = Barge::Client.new(access_token: ENV['DO_KEY'])
end
def droplets
@_droplets ||= client.droplet.all[:droplets].map { |drop| DropletDecorator.new(drop) }
end
def list
puts droplets
end
def list_sizes
puts sizes
end
def sizes
@_sizes ||= client.size.all.sizes.map { |size| SizeDecorator.new(size) }
end
def list_regions
puts regions
end
def regions
@_regions ||= client.region.all.regions.map {|region| RegionDecorator.new(region) }
end
def list_images
puts images
end
def images
@_images ||= client.image.all.images.map { |image| ImageDecorator.new(image) }
end
def create
preload
options = {}
ask "Name of droplet" do |answer|
options[:name] = answer
"continue"
end
ask "Region of droplet (region / list)" do |answer|
region = ""
if answer == "list"
list_regions
region = ""
elsif !regions.map(&:slug).include? answer
puts "Region #{answer} not found. Try 'list'"
region = ""
else
region = answer
options[:region] = region
end
region
end
ask "What size instance? ([1]-#{sizes.size},list)" do |answer|
size = ""
case answer
when "list"
sizes.each_with_index do |size, index|
puts "#{index + 1} - #{size.slug}"
end
size = ""
when "1".."#{sizes.size - 1}"
size = sizes.map(&:slug)[Integer(answer) - 1]
options[:size] = size
else
puts "Size unexpected: #{answer}"
size = ""
end
end
ask "Image name? ([1]-#{images.size}, list)" do |answer|
image = ""
case answer
when "list"
images.each_with_index do |image, index|
puts "#{index + 1} - #{image}"
end
when "0".."#{images.size}"
image = images.map(&:slug)[Integer(answer) - 1]
options[:image] = image
else
puts "Image unexpected: #{answer}"
image = ""
end
image
end
ask "ssh key names" do |answer|
ssh_keys = []
unless answer.empty?
ssh_keys << answer
end
options[:ssh_keys] = ssh_keys
ssh_keys
end
ask "Enable backup? (yes / no)" do |answer|
enable_backup = nil
if answer.downcase == 'yes'
enable_backup = true
else
enable_backup = false
end
options[:backups] = enable_backup
"continue"
end
ask "Enable ipv6? (yes / no)" do |answer|
enable_ipv6 = nil
if answer.downcase == 'yes'
enable_backup = true
else
enable_backup = false
end
options[:ipv6] = enable_ipv6
"continue"
end
puts options
confirm "Create a new image? (yes / no)", "yes" do
puts "Image being created"
puts client.droplet.create(options).success?
end
end
def destroy
droplet = nil
ask "What is the ID of the droplet? (droplet_id / list)" do |answer|
continue = nil
if answer.downcase == "list"
puts droplets
else
droplet = find_droplet(answer)
if droplet
continue = true
else
puts "Droplet #{answer} could not be found \n"
end
end
continue.to_s
end
ask "Are you sure you want to delete: #{droplet.name}? (YES / [NO] / list)" do |answer|
if answer == "YES"
droplet.destroy(client, confirm)
else
puts "OK, #{droplet.name} was not deleted"
end
"continue"
end
end
def snapshot(droplet_id, snapshot_name)
client.droplet.snapshot(droplet_id, name: snapshot_name)
end
def test
puts "Are you sure? (YES / [NO]) "
if $stdin.gets.chomp! == "YES"
puts "full steam ahead"
else
puts "Phew, avoided that one"
end
end
private
def preload
print 'Hang on while I connect to Digital Ocean...'
[:regions, :sizes, :images].each do |preload|
public_send(preload)
print '...'
end
puts ''
end
def ask(question)
answer = ""
while answer.empty? do
puts question
answer = $stdin.gets.chomp!
if quit?(answer)
exit
else
answer = yield answer
end
end
end
def confirm(question, confirmation)
puts question
yield if $stdin.gets.chomp! == confirmation
end
def quit?(response)
response.downcase == 'exit' || response.downcase == 'q'
end
def find_droplet(droplet_id)
droplet = nil
catch(:done) do
droplets.each do |drop|
if drop.id == droplet_id
droplet = drop
throw :done
end
end
end
droplet
end
end
class DropletNotFoundError < StandardError; end
class SizeDecorator < SimpleDelegator
def to_s
<<-eos
Memory: #{slug.capitalize}
Disk: #{disk}GB
Transfers: #{transfer}Gib
Price / Month: $#{price_monthly}
Price / Hour: $#{price_hourly}
Available Regions #{regions}
eos
end
end
class DropletDecorator < SimpleDelegator
attr_reader :definition, :droplets
def destroy(client, confirm)
if confirm
client.droplet.destroy(id)
end
end
def to_s
<<-eos
ID: #{id}
Name: #{name}
Region: #{region.name} / #{region.slug}
OS: #{kernel.name} - #{kernel.version}
Memory Size: #{memory}
Disk Size: #{disk}
eos
end
end
class RegionDecorator < SimpleDelegator
attr_reader :definition
def to_s
"#{slug} (#{name})"
end
end
class ImageDecorator < SimpleDelegator
def to_s
"#{slug} (#{name})"
end
end
digital_ocean = DigitalOcean.new
commands = %w(list regions sizes create destroy)
# TODO - REPL command interface
arg = ARGV.first.downcase
if commands.include? arg
digital_ocean.send(arg)
elsif arg == "help"
puts commands
else
puts "Command unknown. Try one of these:"
puts commands
end
# case arg
# when "help"
# puts commands
# when "list"
# puts digital_ocean.droplets
# when "create"
# puts "Hang on while I connect to Digital Ocean..."
# [:regions, :sizes, :images].each do |preload|
# digital_ocean.public_send(preload)
# print "..."
# end
# puts ""
# digital_ocean.create
# when "regions"
# digital_ocean.list_regions
# when "sizes"
# digital_ocean.list_sizes
# when "destroy"
# digital_ocean.destroy
# when "test"
# digital_ocean.test
# else
# puts commands
# end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment