class Cult::Drivers::VultrDriver
Attributes
api_key[R]
Public Class Methods
new(api_key:)
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 11 def initialize(api_key:) @api_key = api_key end
setup!()
click to toggle source
Calls superclass method
Cult::Driver::setup!
# File lib/cult/drivers/vultr_driver.rb, line 175 def self.setup! super url = "https://my.vultr.com/settings/#settingsapi" puts "Vultr does not generate multiple API keys, so you'll need to " "create one (if it does not exist). You can access your API key " "at the following URL:" puts puts " #{url}" puts CLI.launch_browser(url) if CLI.yes_no?("Launch browser?") api_key = CLI.prompt("API Key") unless api_key.match(/^[A-Z2-7]{36}$/) puts "That doesn't look like an API key, but I'll trust you" end inst = new(api_key: api_key) return { api_key: api_key, driver: driver_name, configurations: { sizes: inst.sizes, zones: inst.zones, images: inst.images, } } end
with_api_key(method_name)
click to toggle source
This sets the Vultr API key to this instance's api key for the duration of a method call and restores it afterwards.
# File lib/cult/drivers/vultr_driver.rb, line 18 def self.with_api_key(method_name) unwrapped_name = "#{method_name}_no_api_key".to_sym alias_method unwrapped_name, method_name define_method(method_name) do |*args, &block| old_api_key = Vultr.api_key begin Vultr.api_key = self.api_key return send(unwrapped_name, *args, &block) ensure Vultr.api_key = old_api_key end end end
Public Instance Methods
destroy!(id:, ssh_key_id: nil)
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 104 def destroy!(id:, ssh_key_id: nil) Vultr::Server.destroy(SUBID: id) destroy_ssh_key!(ssh_key_id: ssh_key_id) if ssh_key_id end
destroy_ssh_key!(ssh_key_id:)
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 110 def destroy_ssh_key!(ssh_key_id:) Vultr::SSHKey.destroy(SSHKEYID: ssh_key_id) end
fetch_ip(list, type)
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 97 def fetch_ip(list, type) goal = (type == :public ? "main_ip" : "private") r = list.find{ |v| v["type"] == goal } r.nil? ? nil : r["ip"] end
images_map()
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 43 def images_map Vultr::OS.list[:result].select do |k, v| # Doing our part to kill x86/32 v['arch'] == 'x64' end.map do |k,v| [slugify(distro_name(v["name"])), v["OSID"]] end.reject do |k,v| %w(custom snapshot backup application).include?(k) || k.match(/^windows/) end.to_h end
provision!(name:, size:, zone:, image:, ssh_public_key:)
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 116 def provision!(name:, size:, zone:, image:, ssh_public_key:) transaction do |xac| ssh_key_id = upload_ssh_key(file: ssh_public_key) xac.rollback do destroy_ssh_key!(ssh_key_id: ssh_key_id) end sizeid = fetch_mapped(name: :size, from: sizes_map, key: size) imageid = fetch_mapped(name: :image, from: images_map, key: image) zoneid = fetch_mapped(name: :zone, from: zones_map, key: zone) r = Vultr::Server.create(DCID: zoneid, OSID: imageid, VPSPLANID: sizeid, enable_ipv6: 'yes', enable_private_network: 'yes', label: name, hostname: name, SSHKEYID: ssh_key_id) subid = r[:result]["SUBID"] xac.rollback do destroy!(id: subid) end # Wait until it's active, it won't have an IP until then backoff_loop do r = Vultr::Server.list(SUBID: subid)[:result] break if r['status'] == 'active' end iplist4 = Vultr::Server.list_ipv4(SUBID: subid)[:result].values[0] iplist6 = Vultr::Server.list_ipv6(SUBID: subid)[:result].values[0] host = fetch_ip(iplist4, :public) await_ssh(host) return { name: name, size: size, zone: zone, image: image, ssh_key_id: ssh_key_id, id: subid, created_at: Time.now.iso8601, host: host, ipv4_public: host, ipv4_private: fetch_ip(iplist4, :private), ipv6_public: fetch_ip(iplist6, :public), ipv6_private: fetch_ip(iplist6, :private), meta: {} } end end
sizes_map()
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 59 def sizes_map Vultr::Plans.list[:result].values.select do |v| v["plan_type"] == 'SSD' end.map do |v| if (m = v["name"].match(/^(\d+) ([MGTP]B) RAM/i)) _, ram, unit = *m ram = ram.to_i if unit == "MB" && ram >= 1024 ram = ram / 1024 unit = "GB" end if unit == "GB" && ram >= 1024 ram = ram / 1024 unit = "TB" end ["#{ram}#{unit}".downcase, v["VPSPLANID"] ] else nil end end.compact.to_h end
upload_ssh_key(file:)
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 89 def upload_ssh_key(file:) key = ssh_key_info(file: file) Vultr::SSHKey.create(name: "Cult: #{key[:name]}", ssh_key: key[:data])[:result]["SSHKEYID"] end
zones_map()
click to toggle source
# File lib/cult/drivers/vultr_driver.rb, line 33 def zones_map Vultr::Regions.list[:result].map do |k, v| [slugify(v["regioncode"]), v["DCID"]] end.to_h end