-
-
Save stephaneliu/d717f5c9d7185ac9d145 to your computer and use it in GitHub Desktop.
Error
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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