class Clc::Client

Attributes

account[R]
connection[R]

Public Class Methods

new(params = {}) click to toggle source
# File lib/clc/client.rb, line 10
def initialize(params = {})
  @connection = Faraday.new(:url => params[:endpoint] || 'https://api.ctl.io') do |builder|
    builder.use Clc::CloudExceptions::Handler
    builder.request :json
    builder.response :json
    builder.adapter Faraday.default_adapter
  end

  setup_logging(@connection.builder, params[:verbosity]) if params[:verbosity]

  response = @connection.post(
    '/v2/authentication/login',
    'username' => params[:username] || ENV['CLC_USERNAME'],
    'password' => params[:password] || ENV['CLC_PASSWORD']
  )

  @connection.authorization :Bearer, response.body.fetch('bearerToken')

  @account = response.body.fetch('accountAlias')
end

Public Instance Methods

create_group(params) click to toggle source
# File lib/clc/client.rb, line 139
def create_group(params)
  connection.post("/v2/groups/#{account}", params).body
end
create_ip_address(server_id, params) click to toggle source
# File lib/clc/client.rb, line 97
def create_ip_address(server_id, params)
  body = connection.post(
    "/v2/servers/#{account}/#{server_id}/publicIPAddresses",
    params
  ).body

  async_response('links' => [body])
end
create_server(params) click to toggle source

TODO: Takes a lot of time

# File lib/clc/client.rb, line 56
def create_server(params)
  body = connection.post("/v2/servers/#{account}", params).body
  async_response(body)
end
delete_ip_address(server_id, ip_string) click to toggle source
# File lib/clc/client.rb, line 106
def delete_ip_address(server_id, ip_string)
  url = "/v2/servers/#{account}/#{server_id}/publicIPAddresses/#{ip_string}"
  body = connection.delete(url).body

  async_response('links' => [body])
end
delete_server(id) click to toggle source
# File lib/clc/client.rb, line 61
def delete_server(id)
  body = connection.delete("v2/servers/#{account}/#{id}").body
  async_response(body)
end
follow(link) click to toggle source
# File lib/clc/client.rb, line 143
def follow(link)
  connection.get(link['href']).body
end
list_datacenters() click to toggle source
# File lib/clc/client.rb, line 31
def list_datacenters
  connection.get("v2/datacenters/#{@account}").body
end
list_groups(datacenter_id) click to toggle source
# File lib/clc/client.rb, line 131
def list_groups(datacenter_id)
  datacenter = show_datacenter(datacenter_id, true)

  root_group_link = datacenter['links'].detect { |link| link['rel'] == 'group' }

  flatten_groups(show_group(root_group_link['id']))
end
list_ip_addresses(server_id) click to toggle source
# File lib/clc/client.rb, line 113
def list_ip_addresses(server_id)
  server = show_server(server_id)

  ip_links = server['links'].select do |link|
    link['rel'] == 'publicIPAddress'
  end

  ip_links.map { |link| follow(link).merge('id' => link['id']) }
end
list_servers(datacenter_id = 'ca1') click to toggle source
# File lib/clc/client.rb, line 39
def list_servers(datacenter_id = 'ca1')
  datacenter = show_datacenter(datacenter_id)
  group_links = datacenter['links'].select { |l| l['rel'] == 'group' }

  groups = group_links.map do |link|
    group = connection.get("v2/groups/#{@account}/#{link['id']}?serverDetail=detailed").body
    flatten_groups(group)
  end.flatten

  groups.map { |group| group['servers'] }.flatten.compact
end
list_templates(datacenter_id) click to toggle source
# File lib/clc/client.rb, line 92
def list_templates(datacenter_id)
  url = "/v2/datacenters/#{account}/#{datacenter_id}/deploymentCapabilities"
  connection.get(url).body.fetch('templates')
end
power_off_server(id) click to toggle source
# File lib/clc/client.rb, line 86
def power_off_server(id)
  response = connection.post("/v2/operations/#{account}/servers/powerOff", [id])
  body = response.body.first
  async_response(body)
end
power_on_server(id) click to toggle source
# File lib/clc/client.rb, line 80
def power_on_server(id)
  response = connection.post("/v2/operations/#{account}/servers/powerOn", [id])
  body = response.body.first
  async_response(body)
end
reboot_server(id) click to toggle source

TODO: Reboot is slower. Looks like OS-level reboot

# File lib/clc/client.rb, line 74
def reboot_server(id)
  response = connection.post("/v2/operations/#{account}/servers/reboot", [id])
  body = response.body.first
  async_response(body)
end
reset_server(id) click to toggle source

TODO: Reset is quicker. Probably 'hard-reset'

# File lib/clc/client.rb, line 67
def reset_server(id)
  response = connection.post("/v2/operations/#{account}/servers/reset", [id])
  body = response.body.first
  async_response(body)
end
show_datacenter(id, group_links = true) click to toggle source
# File lib/clc/client.rb, line 35
def show_datacenter(id, group_links = true)
  connection.get("v2/datacenters/#{@account}/#{id}?groupLinks=#{group_links}").body
end
show_group(id, params = {}) click to toggle source
# File lib/clc/client.rb, line 127
def show_group(id, params = {})
  connection.get("v2/groups/#{account}/#{id}", params).body
end
show_operation(id) click to toggle source
# File lib/clc/client.rb, line 123
def show_operation(id)
  connection.get("v2/operations/#{account}/status/#{id}").body
end
show_server(id, uuid = false) click to toggle source
# File lib/clc/client.rb, line 51
def show_server(id, uuid = false)
  connection.get("/v2/servers/#{@account}/#{id}?uuid=#{uuid}").body
end
wait_for(operation_id, timeout = 1200) { |status| ... } click to toggle source
# File lib/clc/client.rb, line 147
def wait_for(operation_id, timeout = 1200)
  expire_at = Time.now + timeout
  loop do
    operation = show_operation(operation_id)
    status = operation['status']
    yield status if block_given?

    case status
    when 'succeeded' then return true
    when 'failed', 'unknown' then raise 'Operation Failed' # reason?
    when 'executing', 'resumed', 'notStarted'
      raise 'Operation takes too much time to complete' if Time.now > expire_at
      next sleep(2)
    else
      raise "Operation status unknown: #{status}"
    end
  end
end

Private Instance Methods

async_response(body) click to toggle source
# File lib/clc/client.rb, line 168
def async_response(body)
  check_errors(body)
  extract_links(body)
end
check_errors(body) click to toggle source
# File lib/clc/client.rb, line 173
def check_errors(body)
  if error = body['errorMessage']
    raise error
  elsif body['isQueued'] == false
    raise 'Cloud refused to queue the operation'
  end
end
flatten_groups(group) click to toggle source
# File lib/clc/client.rb, line 198
def flatten_groups(group)
  child_groups = group.delete('groups')
  return [group] unless child_groups && child_groups.any?
  [group] + child_groups.map { |child| flatten_groups(child) }.flatten
end
setup_logging(builder, verbosity) click to toggle source
# File lib/clc/client.rb, line 189
def setup_logging(builder, verbosity)
  case verbosity
  when 1
    builder.response :logger, ::Logger.new(STDOUT)
  when 2
    builder.response :logger, ::Logger.new(STDOUT), :bodies => true
  end
end