module Fog module Compute class Google class Servers < Fog::Collection model Fog::Compute::Google::Server def all(zone: nil, filter: nil, max_results: nil, order_by: nil, page_token: nil) opts = { :filter => filter, :max_results => max_results, :order_by => order_by, :page_token => page_token } if zone data = service.list_servers(zone, **opts).to_h[:items] || [] else data = [] service.list_aggregated_servers(**opts).items.each_value do |scoped_lst| if scoped_lst && scoped_lst.instances data.concat(scoped_lst.instances.map(&:to_h)) end end end load(data) end # TODO: This method needs to take self_links as well as names def get(identity, zone = nil) if zone server = service.get_server(identity, zone).to_h return new(server) elsif identity response = all(:filter => "name eq .*#{identity}", :max_results => 1) server = response.first unless response.empty? return server end rescue ::Google::Apis::ClientError => e raise e unless e.status_code == 404 nil end def bootstrap(public_key_path: nil, **opts) name = "fog-#{Time.now.to_i}" zone_name = "us-central1-f" disks = opts[:disks] if disks.nil? || disks.empty? # create the persistent boot disk source_img = service.images.get_from_family("debian-9") disk_defaults = { :name => name, :size_gb => 10, :zone_name => zone_name, :source_image => source_img.self_link } disk = service.disks.create(**disk_defaults.merge(opts)) disk.wait_for { disk.ready? } disks = [disk] end # TODO: Remove the network init when #360 is fixed network = { :network => "global/networks/default", :access_configs => [{ :name => "External NAT", :type => "ONE_TO_ONE_NAT" }] } # Merge the options with the defaults, overwriting defaults # if an option is provided data = { :name => name, :zone => zone_name, :disks => disks, :network_interfaces => [network], :public_key => get_public_key(public_key_path), :username => ENV["USER"] }.merge(opts) data[:machine_type] = "n1-standard-1" unless data[:machine_type] server = new(data) server.save server.wait_for { ready? } # Set the disk to be autodeleted # true - autodelete setting # nil - device name (not needed if there's only one disk) # false - set async to false so set the property synchronously server.set_disk_auto_delete(true, nil, false) server end private # Defaults to: # 1. ~/.ssh/google_compute_engine.pub # 2. ~/.ssh/id_rsa.pub PUBLIC_KEY_DEFAULTS = %w( ~/.ssh/google_compute_engine.pub ~/.ssh/id_rsa.pub ).freeze def get_public_key(public_key_path) unless public_key_path PUBLIC_KEY_DEFAULTS.each do |path| if File.exist?(File.expand_path(path)) public_key_path = path break end end end if public_key_path.nil? || public_key_path.empty? raise Fog::Errors::Error.new("Cannot bootstrap instance without a public key") end File.read(File.expand_path(public_key_path)) end end end end end