class Chef::Knife::Cloud::FogService

Public Class Methods

new(**kwargs) click to toggle source
Calls superclass method
# File lib/chef/knife/cloud/fog/service.rb, line 15
def initialize(**kwargs)
  super
  load_fog_gem
end

Public Instance Methods

add_api_endpoint() click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 205
def add_api_endpoint
  raise Chef::Exceptions::Override, "You must override add_api_endpoint in #{self} to add endpoint in auth_params for connection"
end
allocate_address(pool = nil) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 171
def allocate_address(pool = nil)
  response = connection.allocate_address(pool)
  response.body
rescue Fog::Compute::OpenStack::NotFound => e
  error_message = "Floating ip pool not found."
  ui.error(error_message)
  raise CloudExceptions::NotFoundError, "#{e.message}"
rescue Excon::Error::Forbidden => e
  handle_excon_exception(CloudExceptions::KnifeCloudError, e)
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::KnifeCloudError, e)
end
associate_address(*args) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 184
def associate_address(*args)
  connection.associate_address(*args)
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::KnifeCloudError, e)
end
connection() click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 30
def connection
  add_api_endpoint
  @connection ||= begin
                    Fog::Compute.new(@auth_params)
                  rescue Excon::Error::Unauthorized => e
                    error_message = "Connection failure, please check your username and password."
                    ui.fatal(error_message)
                    raise CloudExceptions::ServiceConnectionError, "#{e.message}. #{error_message}"
                  rescue Excon::Error::Socket => e
                    error_message = "Connection failure, please check your authentication URL."
                    ui.fatal(error_message)
                    raise CloudExceptions::ServiceConnectionError, "#{e.message}. #{error_message}"
                  end
end
create_server(options = {}) click to toggle source

cloud server specific implementation methods for commands.

# File lib/chef/knife/cloud/fog/service.rb, line 64
def create_server(options = {})
  begin
    add_custom_attributes(options[:server_def])
    server = connection.servers.create(options[:server_def])
  rescue Excon::Error::BadRequest => e
    response = Chef::JSONCompat.from_json(e.response.body)
    if response["badRequest"]["code"] == 400
      message = "Bad request (400): #{response["badRequest"]["message"]}"
      ui.fatal(message)
    else
      message = "Unknown server error (#{response["badRequest"]["code"]}): #{response["badRequest"]["message"]}"
      ui.fatal(message)
    end
    raise CloudExceptions::ServerCreateError, message
  rescue Fog::Errors::Error => e
    raise CloudExceptions::ServerCreateError, e.message
  end

  print "\n#{ui.color("Waiting for server [wait time = #{options[:server_create_timeout]}]", :magenta)}"

  # wait for it to be ready to do stuff
  server.wait_for(Integer(options[:server_create_timeout])) { print "."; ready? }

  puts("\n")
  server
end
delete_server(server_name) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 91
def delete_server(server_name)
  server = get_server(server_name)
  msg_pair("Instance Name", get_server_name(server))
  msg_pair("Instance ID", server.id)

  puts "\n"
  ui.confirm("Do you really want to delete this server")

  # delete the server
  server.destroy
rescue NoMethodError
  error_message = "Could not locate server '#{server_name}'."
  ui.error(error_message)
  raise CloudExceptions::ServerDeleteError, error_message
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::ServerDeleteError, e)
end
delete_server_on_failure(server = nil) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 201
def delete_server_on_failure(server = nil)
  server.destroy unless server.nil?
end
disassociate_address(*args) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 190
def disassociate_address(*args)
  connection.disassociate_address(*args)
rescue Fog::Compute::OpenStack::NotFound
  error_message = "Floating ip not found."
  ui.error(error_message)
rescue Excon::Error::UnprocessableEntity => e
  handle_excon_exception(CloudExceptions::KnifeCloudError, e)
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::KnifeCloudError, e)
end
get_address(address_id) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 165
def get_address(address_id)
  connection.get_address(address_id)
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::KnifeCloudError, e)
end
get_address_ip(response) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 161
def get_address_ip(response)
  response.body["floating_ip"]["ip"] if response.body["floating_ip"]
end
get_flavor(name_or_id) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 223
def get_flavor(name_or_id)
  connection.flavors.find { |f| f.name == name_or_id || f.id == name_or_id }
end
get_image(name_or_id) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 219
def get_image(name_or_id)
  connection.images.find { |img| img.name =~ /#{name_or_id}/ || img.id == name_or_id }
end
get_server(instance_id) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 213
def get_server(instance_id)
  connection.servers.get(instance_id)
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::KnifeCloudError, e)
end
get_server_name(server) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 209
def get_server_name(server)
  server.name
end
handle_excon_exception(exception_class, e) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 124
def handle_excon_exception(exception_class, e)
  error_message = if e.response
                    response = Chef::JSONCompat.from_json(e.response.body)
                    "Unknown server error (#{response[response.keys[0]]["code"]}): #{response[response.keys[0]]["message"]}"
                  else
                    "Unknown server error : #{e.message}"
                  end
  ui.fatal(error_message)
  raise exception_class, error_message
end
is_image_windows?(image) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 244
def is_image_windows?(image)
  image_info = connection.images.get(image)
  !image_info.nil? ? image_info.platform == "windows" : false
end
list_addresses() click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 141
def list_addresses
  connection.addresses.all
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::CloudAPIException, e)
end
list_resource_configurations() click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 135
def list_resource_configurations
  connection.flavors.all
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::CloudAPIException, e)
end
load_fog_gem() click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 20
def load_fog_gem
  # Load specific version of fog-core. Any other classes/modules using fog-core are loaded after this.
  gem "fog-core", config[:cloud_fog_version]
  require "fog/core"
  Chef::Log.debug("Using fog-core version: #{Gem.loaded_specs["fog-core"].version}")
rescue Exception => ex
  Chef::Log.error "Error loading fog-core gem: #{ex}"
  exit 1
end
network() click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 45
def network
  @network ||= begin
                Fog::Network.new(@auth_params)
               rescue Excon::Error::Unauthorized => e
                 error_message = "Connection failure, please check your username and password."
                 ui.fatal(error_message)
                 raise CloudExceptions::ServiceConnectionError, "#{e.message}. #{error_message}"
               rescue Excon::Error::Socket => e
                 error_message = "Connection failure, please check your authentication URL."
                 ui.fatal(error_message)
                 raise CloudExceptions::ServiceConnectionError, "#{e.message}. #{error_message}"
               rescue Fog::Errors::NotFound => e
                 error_message = "No Network service found. This command is unavailable with current cloud."
                 ui.fatal(error_message)
                 raise CloudExceptions::NetworkNotFoundError, "#{e.message}. #{error_message}"
              end
end
release_address(address_id) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 147
def release_address(address_id)
  response = get_address(address_id)
  msg_pair("IP address", get_address_ip(response))
  puts
  ui.confirm("Do you really want to delete this ip")
  connection.release_address(address_id)
rescue Fog::Compute::OpenStack::NotFound => e
  error_message = "Floating ip not found."
  ui.error(error_message)
  raise CloudExceptions::NotFoundError, "#{e.message}"
rescue Excon::Error::BadRequest => e
  handle_excon_exception(CloudExceptions::KnifeCloudError, e)
end
server_summary(server, columns_with_info = []) click to toggle source
# File lib/chef/knife/cloud/fog/service.rb, line 227
def server_summary(server, columns_with_info = [])
  # columns_with_info is array of hash with label, key and attribute extraction callback, ex [{:label => "Label text", :key => 'key', value => 'the_actual_value', value_callback => callback_method to extract/format the required value}, ...]
  list = []
  columns_with_info.each do |col_info|
    value = if col_info[:value].nil?
              (col_info[:value_callback].nil? ? server.send(col_info[:key]).to_s : col_info[:value_callback].call(server.send(col_info[:key])))
            else
              col_info[:value]
            end
    unless value.nil? || value.empty?
      list << ui.color(col_info[:label], :bold)
      list << value
    end
  end
  puts ui.list(list, :uneven_columns_across, 2) if columns_with_info.length > 0
end