class Fog::Scaleway::Compute::Mock

Constants

INITIAL_IMAGES
PRODUCTS

Public Class Methods

data() click to toggle source
# File lib/fog/scaleway/compute.rb, line 260
def self.data
  @data ||= Hash.new do |hash, token|
    hash[token] = {
      servers: {},
      user_data: Hash.new({}),
      volumes: {},
      snapshots: {},
      images: Hash[INITIAL_IMAGES.map { |i| [i['id'], i] }],
      ips: {},
      security_groups: {},
      security_group_rules: Hash.new({}),
      bootscripts: Hash[INITIAL_IMAGES.map do |i|
        [i['default_bootscript']['id'], i['default_bootscript']]
      end],
      tasks: {},
      containers: {},
      server_actions: Hash.new(%w[poweron poweroff reboot terminate])
    }
  end
end
new(options) click to toggle source
# File lib/fog/scaleway/compute.rb, line 281
def initialize(options)
  @token = options[:scaleway_token]
end
reset() click to toggle source
# File lib/fog/scaleway/compute.rb, line 285
def self.reset
  @data = nil
end

Public Instance Methods

create_image(name, arch, root_volume, options = {}) click to toggle source
# File lib/fog/scaleway/requests/compute/create_image.rb, line 20
def create_image(name, arch, root_volume, options = {})
  body = {
    organization: @organization,
    name: name,
    arch: arch,
    root_volume: root_volume
  }

  body.merge!(options)

  body = jsonify(body)

  creation_date = now

  root_volume = lookup(:snapshots, body['root_volume'])

  image = {
    'default_bootscript' => body['default_bootscript'],
    'creation_date' => creation_date,
    'name' => body['name'],
    'modification_date' => creation_date,
    'organization' => body['organization'],
    'extra_volumes' => '[]',
    'arch' => body['arch'],
    'id' => Fog::UUID.uuid,
    'root_volume' => {
      'size' => root_volume['size'],
      'id' => root_volume['id'],
      'volume_type' => root_volume['volume_type'],
      'name' => root_volume['name']
    },
    'public' => false
  }

  data[:images][image['id']] = image

  response(status: 201, body: { 'image' => image })
end
create_ip(options = {}) click to toggle source
# File lib/fog/scaleway/requests/compute/create_ip.rb, line 17
def create_ip(options = {})
  body = {
    organization: @organization
  }

  body.merge!(options)

  body = jsonify(body)

  server = lookup(:servers, body['server']) if body['server']

  ip = {
    'organization' => body['organization'],
    'reverse' => nil,
    'id' => Fog::UUID.uuid,
    'server' => nil,
    'address' => Fog::Mock.random_ip
  }

  if server
    ip['server'] = {
      'id' => server['id'],
      'name' => server['name']
    }
  end

  if server && (public_ip = server['public_ip'])
    if public_ip['dynamic']
      ip['id'] = public_ip['id']
      ip['address'] = public_ip['address']
    else
      message = "Server '#{server['id']}' is already attached to an IP address"
      raise_invalid_request_error(message)
    end
  end

  data[:ips][ip['id']] = ip

  if server
    server['public_ip'] = {
      'dynamic' => false,
      'id' => ip['id'],
      'address' => ip['address']
    }
  end

  response(status: 201, body: { 'ip' => ip })
end
create_security_group(name, options = {}) click to toggle source
# File lib/fog/scaleway/requests/compute/create_security_group.rb, line 18
def create_security_group(name, options = {})
  body = {
    organization: @organization,
    name: name
  }

  body.merge!(options)

  body = jsonify(body)

  security_group = {
    'description' => body['description'],
    'enable_default_security' => body.fetch('enable_default_security', true),
    'servers' => [],
    'organization' => body['organization'],
    'organization_default' => body.fetch('organization_default', false),
    'id' => Fog::UUID.uuid,
    'name' => body['name']
  }

  if security_group['organization_default'] && default_security_group
    raise_conflict('Cannot have more than one organization default group')
  end

  data[:security_groups][security_group['id']] = security_group

  response(status: 201, body: { 'security_group' => security_group })
end
create_security_group_rule(security_group_id, action, direction, ip_range, protocol, dest_port_from = nil) click to toggle source
# File lib/fog/scaleway/requests/compute/create_security_group_rule.rb, line 15
def create_security_group_rule(security_group_id, action, direction, ip_range, protocol, dest_port_from = nil)
  body = {
    action: action,
    direction: direction,
    ip_range: ip_range,
    protocol: protocol,
    dest_port_from: dest_port_from
  }

  body = jsonify(body)

  rules = data[:security_group_rules][security_group_id].values

  position = (rules.map { |r| r[:position] }.max || 0) + 1

  rule = {
    'direction' => body['direction'],
    'protocol' => body['protocol'],
    'ip_range' => body['ip_range'],
    'dest_port_from' => body['dest_port_from'],
    'action' => body['action'],
    'position' => position,
    'dest_port_to' => nil,
    'editable' => nil,
    'id' => Fog::UUID.uuid
  }

  data[:security_group_rules][security_group_id][rule['id']] = rule

  response(status: 201, body: { 'rule' => rule })
end
create_server(name, image, volumes, options = {}) click to toggle source
# File lib/fog/scaleway/requests/compute/create_server.rb, line 20
def create_server(name, image, volumes, options = {})
  body = {
    organization: @organization,
    name: name,
    image: image,
    volumes: volumes
  }

  body.merge!(options)

  body = jsonify(body)

  image = lookup(:images, body['image'])

  commercial_type, product_server = lookup_product_server(body.fetch('commercial_type', 'VC1S'))
  raise_invalid_request_error('Validation Error') unless commercial_type

  unless image['arch'] == product_server['arch']
    message = "Image '#{image['id']}' arch is not '#{product_server['arch']}'"
    raise_invalid_request_error(message)
  end

  creation_date = now

  volumes = {}
  body['volumes'].each do |index, volume|
    volume = lookup(:volumes, volume['id'])

    if volume['server']
      message = "volume #{volume['id']} is already attached to a server"
      raise_invalid_request_error(message)
    end

    volumes[index] = volume
  end

  root_volume = image['root_volume']
  volumes['0'] = {
    'size' => root_volume['size'],
    'name' => root_volume['name'],
    'modification_date' => creation_date,
    'organization' => body['organization'],
    'export_uri' => nil,
    'creation_date' => creation_date,
    'id' => Fog::UUID.uuid,
    'volume_type' => root_volume['volume_type'],
    'server' => nil
  }

  public_ip = nil
  if body['public_ip']
    public_ip = lookup(:ips, body['public_ip'])

    public_ip = {
      'dynamic' => false,
      'id' => public_ip['id'],
      'address' => public_ip['address']
    }
  end

  default_bootscript_id = image['default_bootscript']['id']
  bootscript_id = body.fetch('bootscript', default_bootscript_id)
  bootscript = lookup(:bootscripts, bootscript_id)

  dynamic_ip_required = !public_ip && body.fetch('dynamic_ip_required', true)

  enable_ipv6 = body.fetch('enable_ipv6', false)
  if enable_ipv6 && !product_server['network']['ipv6_support']
    raise_invalid_request_error("Cannot enable ipv6 on #{commercial_type}")
  end

  if body['security_group']
    security_group = lookup(:security_groups, body['security_group'])
  else
    security_group = default_security_group
    security_group ||= create_default_security_group
  end

  server = {
    'arch' => image['arch'],
    'bootscript' => bootscript,
    'commercial_type' => commercial_type,
    'creation_date' => creation_date,
    'dynamic_ip_required' => dynamic_ip_required,
    'enable_ipv6' => enable_ipv6,
    'extra_networks' => [],
    'hostname' => body['name'],
    'id' => Fog::UUID.uuid,
    'image' => image,
    'ipv6' => nil,
    'location' => nil,
    'modification_date' => creation_date,
    'name' => body['name'],
    'organization' => body['organization'],
    'private_ip' => nil,
    'public_ip' => public_ip,
    'security_group' => {
      'id' => security_group['id'],
      'name' => security_group['name']
    },
    'state' => 'stopped',
    'state_detail' => '',
    'tags' => body.fetch('tags', []),
    'volumes' => volumes
  }

  data[:servers][server['id']] = server

  data[:volumes][server['volumes']['0']['id']] = server['volumes']['0']

  server['volumes'].each_value do |volume|
    volume['server'] = {
      'id' => server['id'],
      'name' => server['name']
    }
  end

  response(status: 201, body: { 'server' => server })
end
create_snapshot(name, volume_id) click to toggle source
# File lib/fog/scaleway/requests/compute/create_snapshot.rb, line 13
def create_snapshot(name, volume_id)
  body = {
    organization: @organization,
    name: name,
    volume_id: volume_id
  }

  body = jsonify(body)

  base_volume = lookup(:volumes, body['volume_id'])

  server_id = base_volume['server'] && base_volume['server']['id']
  server = lookup(:servers, server_id) if server_id
  in_use = server && server['state'] != 'stopped'

  raise_invalid_request_error('server must be stopped to snapshot') if in_use

  creation_date = now

  snapshot = {
    'state' => 'snapshotting',
    'base_volume' => {
      'id' => base_volume['id'],
      'name' => base_volume['name']
    },
    'name' => body['name'],
    'modification_date' => creation_date,
    'organization' => body['organization'],
    'size' => base_volume['size'],
    'id' => Fog::UUID.uuid,
    'volume_type' => base_volume['volume_type'],
    'creation_date' => creation_date
  }

  data[:snapshots][snapshot['id']] = snapshot

  response(status: 201, body: { 'snapshot' => snapshot })
end
create_volume(name, volume_type, options) click to toggle source
# File lib/fog/scaleway/requests/compute/create_volume.rb, line 29
def create_volume(name, volume_type, options)
  if options[:size].nil? && options[:base_volume].nil? && options[:base_snapshot].nil?
    raise ArgumentError, 'size, base_volume or base_snapshot are required to create a volume'
  end

  body = {
    organization: @organization,
    name: name,
    volume_type: volume_type
  }

  if !options[:size].nil?
    body[:size] = options[:size]
  elsif !options[:base_volume].nil?
    body[:base_volume] = options[:base_volume]
  else
    body[:base_snapshot] = options[:base_snapshot]
  end

  body = jsonify(body)

  creation_date = now

  if body['size']
    size = body['size']
  elsif body['base_volume']
    base_volume = lookup(:volumes, body['base_volume'])

    server_id = base_volume['server'] && base_volume['server']['id']
    server = lookup(:servers, server_id) if server_id
    in_use = server && server['state'] != 'stopped'

    raise_invalid_request_error('Base volume is in use') if in_use

    size = base_volume['size']
  elsif body['base_snapshot']
    base_snapshot = lookup(:snapshots, body['base_snapshot'])
    size = base_snapshot['size']
  end

  volume = {
    'size' => size,
    'name' => body['name'],
    'modification_date' => creation_date,
    'organization' => body['organization'],
    'export_uri' => nil,
    'creation_date' => creation_date,
    'id' => Fog::UUID.uuid,
    'volume_type' => body['volume_type'],
    'server' => nil
  }

  data[:volumes][volume['id']] = volume

  response(status: 201, body: { 'volume' => volume })
end
delete_image(image_id) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_image.rb, line 11
def delete_image(image_id)
  image = lookup(:images, image_id)

  data[:images].delete(image['id'])

  data[:servers].each_value do |server|
    if server['image'] && server['image']['id'] == image['id']
      server['image'] = nil
    end
  end

  response(status: 204)
end
delete_ip(ip_id) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_ip.rb, line 11
def delete_ip(ip_id)
  ip = lookup(:ips, ip_id)

  data[:ips].delete(ip['id'])

  if ip['server']
    server = lookup(:servers, ip['server']['id'])

    server['public_ip'] = if server['dynamic_ip_required']
                            create_dynamic_ip
                          end
  end

  response(status: 204)
end
delete_security_group(security_group_id) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_security_group.rb, line 11
def delete_security_group(security_group_id)
  security_group = lookup(:security_groups, security_group_id)

  unless security_group['servers'].empty?
    raise_conflict('Group is in use. You cannot delete it.')
  end

  if security_group['organization_default']
    raise_conflict('Group is default group. You cannot delete it.')
  end

  data[:security_groups].delete(security_group['id'])

  data[:security_group_rules].delete(security_group['id'])

  response(status: 204)
end
delete_security_group_rule(security_group_id, rule_id) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_security_group_rule.rb, line 11
def delete_security_group_rule(security_group_id, rule_id)
  security_group = lookup(:security_groups, security_group_id)

  unless data[:security_group_rules][security_group['id']].delete(rule_id)
    raise_unknown_resource(rule_id)
  end

  response(status: 204)
end
delete_server(server_id) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_server.rb, line 11
def delete_server(server_id)
  server = lookup(:servers, server_id)

  if server['state'] != 'stopped'
    raise_invalid_request_error('server should be stopped')
  end

  data[:servers].delete(server['id'])

  data[:user_data].delete(server['id'])

  data[:server_actions].delete(server['id'])

  if server['public_ip'] && !server['public_ip']['dynamic']
    ip = lookup(:ips, server['public_ip']['id'])
    ip['server'] = nil
  end

  security_group = lookup(:security_groups, server['security_group']['id'])
  security_group['servers'].reject! { |s| s['id'] == server['id'] }

  volumes = server['volumes'].values
  volumes.each { |volume| volume['server'] = nil }

  response(status: 204)
end
delete_snapshot(snapshot_id) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_snapshot.rb, line 11
def delete_snapshot(snapshot_id)
  snapshot = lookup(:snapshots, snapshot_id)

  in_use = data[:images].any? do |_id, image|
    image['root_volume']['id'] == snapshot['id']
  end

  if in_use
    raise_invalid_request_error('one or more images are attached to this snapshot')
  end

  data[:snapshots].delete(snapshot['id'])

  response(status: 204)
end
delete_task(task_id) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_task.rb, line 11
def delete_task(task_id)
  task = lookup(:tasks, task_id)

  data[:tasks].delete(task['id'])

  response(status: 204)
end
delete_user_data(server_id, key) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_user_data.rb, line 11
def delete_user_data(server_id, key)
  server = lookup(:servers, server_id)

  data[:user_data][server['id']].delete(key)

  response(status: 204)
end
delete_volume(volume_id) click to toggle source
# File lib/fog/scaleway/requests/compute/delete_volume.rb, line 11
def delete_volume(volume_id)
  volume = lookup(:volumes, volume_id)

  if volume['server']
    raise_invalid_request_error('a server is attached to this volume')
  end

  data[:volumes].delete(volume_id)

  data[:snapshots].each_value do |snapshot|
    if snapshot['base_volume'] && snapshot['base_volume']['id'] == volume_id
      snapshot['base_volume'] = nil
    end
  end

  response(status: 204)
end
execute_server_action(server_id, action) click to toggle source
# File lib/fog/scaleway/requests/compute/execute_server_action.rb, line 16
def execute_server_action(server_id, action)
  server = lookup(:servers, server_id)

  started_at = now

  task = {
    'status' => 'pending',
    'terminated_at' => nil,
    'href_from' => "/servers/#{server_id}/action",
    'progress' => 0,
    'started_at' => started_at,
    'id' => Fog::UUID.uuid
  }

  case action
  when 'poweron'
    unless server['state'] == 'stopped'
      raise_invalid_request_error('server should be stopped')
    end

    total_volume_size = server['volumes'].values.map { |v| v['size'] }.reduce(&:+)
    commercial_type, product_server = lookup_product_server(server['commercial_type'])
    # rubocop:disable Metrics/BlockNesting
    if (constraint = product_server['volumes_constraint'])
      min_size = constraint['min_size'] || -Float::INFINITY
      max_size = constraint['max_size'] || Float::INFINITY
      if total_volume_size < min_size || total_volume_size > max_size
        message = "The total volume size of #{commercial_type} instances must be "
        message << if min_size == -Float::INFINITY
                     "equal or below #{max_size / 10**9}GB"
                   elsif max_size == Float::INFINITY
                     "equal or above #{min_size / 10**9}GB"
                   else
                     "between #{min_size / 10**9}GB and #{max_size / 10**9}GB"
                   end
        raise_invalid_request_error(message)
      end
    end
    # rubocop:enable Metrics/BlockNesting

    task['description'] = 'server_batch_poweron'

    server['ipv6'] = create_ipv6 if server['enable_ipv6']

    server['location'] = {
      'platform_id' => Fog::Mock.random_numbers(2),
      'node_id' => Fog::Mock.random_numbers(2),
      'cluster_id' => Fog::Mock.random_numbers(2),
      'zone_id' => @region,
      'chassis_id' => Fog::Mock.random_numbers(2)
    }

    server['private_ip'] = Fog::Mock.random_ip

    if server['dynamic_ip_required'] && server['public_ip'].nil?
      server['public_ip'] = create_dynamic_ip
    end

    server['state'] = 'starting'
    server['state_detail'] = 'provisioning node'
    server['modification_date'] = started_at
  when 'poweroff'
    if server['state'] == 'stopping'
      raise_invalid_request_error('server is being stopped or rebooted')
    elsif server['state'] != 'running'
      raise_invalid_request_error('server should be running')
    end

    task['description'] = 'server_poweroff'

    server['state'] = 'stopping'
    server['state_detail'] = 'stopping'
    server['modification_date'] = started_at
  when 'reboot'
    if server['state'] == 'stopping'
      raise_invalid_request_error('server is being stopped or rebooted')
    elsif server['state'] != 'running'
      raise_invalid_request_error('server should be running')
    end

    task['description'] = 'server_reboot'

    server['state'] = 'stopping'
    server['state_detail'] = 'rebooting'
    server['modification_date'] = started_at
  when 'terminate'
    if server['state'] == 'stopping'
      raise_invalid_request_error('server is being stopped or rebooted')
    elsif server['state'] != 'running'
      raise_invalid_request_error('server should be running')
    end

    task['description'] = 'server_terminate'

    server['state'] = 'stopping'
    server['state_detail'] = 'terminating'
    server['modification_date'] = started_at
  end

  data[:tasks][task['id']] = task

  response(status: 202, body: { 'task' => task })
end
get_bootscript(bootscript_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_bootscript.rb, line 11
def get_bootscript(bootscript_id)
  bootscript = lookup(:bootscripts, bootscript_id)

  response(status: 200, body: { 'bootscript' => bootscript })
end
get_container(container_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_container.rb, line 11
def get_container(container_id)
  container = lookup(:containers, container_id)

  response(status: 200, body: { 'container' => container })
end
get_dashboard() click to toggle source
# File lib/fog/scaleway/requests/compute/get_dashboard.rb, line 11
def get_dashboard # rubocop:disable Naming/AccessorMethodName
  running_servers = data[:servers].select do |_id, s|
    s['state'] == 'running'
  end

  servers_by_types = data[:servers].group_by { |s| s['commercial_type'] }
  servers_count_by_types = Hash[servers_by_types.map { |t, s| [t, s.size] }]

  ips_unused = data[:ips].reject { |ip| ip['server'] }.size

  dashboard = {
    'snapshots_count' => data[:snapshots].size,
    'servers_count' => data[:servers].size,
    'volumes_count' => data[:volumes].size,
    'images_count' => data[:images].size,
    'ips_count' => data[:ips].size,
    'running_servers_count' => running_servers.size,
    'servers_by_types' => servers_count_by_types,
    'ips_unused' => ips_unused
  }

  response(status: 200, body: { 'dashboard' => dashboard })
end
get_image(image_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_image.rb, line 11
def get_image(image_id)
  image = lookup(:images, image_id)

  response(status: 200, body: { 'image' => image })
end
get_ip(ip_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_ip.rb, line 11
def get_ip(ip_id)
  ip = lookup(:ips, ip_id)

  response(status: 200, body: { 'ip' => ip })
end
get_security_group(security_group_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_security_group.rb, line 11
def get_security_group(security_group_id)
  security_group = lookup(:security_groups, security_group_id)

  response(status: 200, body: { 'security_group' => security_group })
end
get_security_group_rule(security_group_id, rule_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_security_group_rule.rb, line 11
def get_security_group_rule(security_group_id, rule_id)
  security_group = lookup(:security_groups, security_group_id)

  rule = data[:security_group_rules][security_group['id']][rule_id]

  raise_unknown_resource(rule_id) unless rule

  response(status: 200, body: { 'rule' => rule })
end
get_server(server_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_server.rb, line 11
def get_server(server_id)
  server = lookup(:servers, server_id)

  elapsed_time = Time.now - Time.parse(server['modification_date'])

  if server['state'] == 'starting' && elapsed_time >= Fog::Mock.delay
    server['state'] = 'running'
    server['state_detail'] = 'booted'
    server['modification_date'] = now
  elsif server['state'] == 'stopping' && elapsed_time >= Fog::Mock.delay
    case server['state_detail']
    when 'stopping'
      server['ipv6'] = nil
      server['location'] = nil
      server['private_ip'] = nil

      if server['public_ip'] && server['public_ip']['dynamic']
        server['public_ip'] = nil
      end

      server['state'] = 'stopped'
      server['state_detail'] = ''
      server['modification_date'] = now
    when 'rebooting'
      server['state'] = 'running'
      server['state_detail'] = 'booted'
      server['modification_date'] = now
    when 'terminating'
      terminate_server(server)
    end
  end

  response(status: 200, body: { 'server' => server })
end
get_snapshot(snapshot_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_snapshot.rb, line 11
def get_snapshot(snapshot_id)
  snapshot = lookup(:snapshots, snapshot_id)

  response(status: 200, body: { 'snapshot' => snapshot })
end
get_task(task_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_task.rb, line 11
def get_task(task_id)
  task = lookup(:tasks, task_id)

  if Time.now - Time.parse(task['started_at']) >= Fog::Mock.delay
    task['status'] = 'success'
    task['terminated_at'] = now
    task['progress'] = 100
  end

  response(status: 200, body: { 'task' => task })
end
get_user_data(server_id, key) click to toggle source
# File lib/fog/scaleway/requests/compute/get_user_data.rb, line 11
def get_user_data(server_id, key)
  server = lookup(:servers, server_id)

  user_data = data[:user_data][server['id']][key]

  raise Excon::Error::NotFound unless user_data

  response(status: 200,
           headers: { 'Content-Type' => 'text/plain' },
           body: user_data)
end
get_volume(volume_id) click to toggle source
# File lib/fog/scaleway/requests/compute/get_volume.rb, line 11
def get_volume(volume_id)
  volume = lookup(:volumes, volume_id)

  response(status: 200, body: { 'volume' => volume })
end
list_bootscripts(filters = {}) click to toggle source
# File lib/fog/scaleway/requests/compute/list_bootscripts.rb, line 11
def list_bootscripts(filters = {})
  bootscripts = data[:bootscripts].values

  if (arch = filters[:arch])
    bootscripts.select! { |b| b['architecture'] == arch }
  end

  response(status: 200, body: { 'bootscripts' => bootscripts })
end
list_containers() click to toggle source
# File lib/fog/scaleway/requests/compute/list_containers.rb, line 11
def list_containers
  containers = data[:containers].values

  response(status: 200, body: { 'containers' => containers })
end
list_images(filters = {}) click to toggle source
# File lib/fog/scaleway/requests/compute/list_images.rb, line 11
def list_images(filters = {})
  images = data[:images].values

  if (organization = filters[:organization])
    images.select! { |i| i['organization'] == organization }
  end

  if (arch = filters[:arch])
    images.select! { |b| b['arch'] == arch }
  end

  response(status: 200, body: { 'images' => images })
end
list_ips() click to toggle source
# File lib/fog/scaleway/requests/compute/list_ips.rb, line 11
def list_ips
  ips = data[:ips].values

  response(status: 200, body: { 'ips' => ips })
end
list_product_servers() click to toggle source
# File lib/fog/scaleway/requests/compute/list_product_servers.rb, line 11
def list_product_servers
  response(status: 200, body: { 'servers' => PRODUCTS['servers'] })
end
list_security_group_rules(security_group_id) click to toggle source
# File lib/fog/scaleway/requests/compute/list_security_group_rules.rb, line 11
def list_security_group_rules(security_group_id)
  security_group = lookup(:security_groups, security_group_id)

  rules = data[:security_group_rules][security_group['id']].values

  response(status: 200, body: { 'rules' => rules })
end
list_security_groups() click to toggle source
# File lib/fog/scaleway/requests/compute/list_security_groups.rb, line 11
def list_security_groups
  security_groups = data[:security_groups].values

  response(status: 200, body: { 'security_groups' => security_groups })
end
list_server_actions(server_id) click to toggle source
# File lib/fog/scaleway/requests/compute/list_server_actions.rb, line 11
def list_server_actions(server_id)
  server = lookup(:servers, server_id)

  actions = data[:server_actions][server['id']]

  response(status: 200, body: { 'actions' => actions })
end
list_servers() click to toggle source
# File lib/fog/scaleway/requests/compute/list_servers.rb, line 11
def list_servers
  servers = data[:servers].values

  response(status: 200, body: { 'servers' => servers })
end
list_snapshots() click to toggle source
# File lib/fog/scaleway/requests/compute/list_snapshots.rb, line 11
def list_snapshots
  snapshots = data[:snapshots].values

  response(status: 200, body: { 'snapshots' => snapshots })
end
list_tasks() click to toggle source
# File lib/fog/scaleway/requests/compute/list_tasks.rb, line 11
def list_tasks
  tasks = data[:tasks].values

  response(status: 200, body: { 'tasks' => tasks })
end
list_user_data(server_id) click to toggle source
# File lib/fog/scaleway/requests/compute/list_user_data.rb, line 11
def list_user_data(server_id)
  server = lookup(:servers, server_id)

  user_data = data[:user_data][server['id']].keys

  response(status: 200, body: { 'user_data' => user_data })
end
list_volumes() click to toggle source
# File lib/fog/scaleway/requests/compute/list_volumes.rb, line 11
def list_volumes
  volumes = data[:volumes].values

  response(status: 200, body: { 'volumes' => volumes })
end
update_image(image_id, body) click to toggle source
# File lib/fog/scaleway/requests/compute/update_image.rb, line 11
def update_image(image_id, body)
  body = jsonify(body)

  image = lookup(:images, image_id)

  default_bootscript = if body['default_bootscript'].is_a?(Hash)
                         lookup(:bootscripts, body['default_bootscript']['id'])
                       elsif body['default_bootscript'].is_a?(String)
                         lookup(:bootscripts, body['default_bootscript'])
                       end

  image['default_bootscript'] = default_bootscript
  image['name'] = body['name']
  image['arch'] = body['arch']

  response(status: 200, body: { 'image' => image })
end
update_ip(ip_id, body) click to toggle source
# File lib/fog/scaleway/requests/compute/update_ip.rb, line 11
def update_ip(ip_id, body)
  body = jsonify(body)

  ip = lookup(:ips, ip_id)

  server = nil
  if (server_id = body['server'])
    server = lookup(:servers, server_id)

    if server['public_ip'] && !server['public_ip']['dynamic']
      message = "Server '#{server['id']}' is already attached to an IP address"
      raise_invalid_request_error(message)
    end

    server = {
      'id' => server['id'],
      'name' => server['name']
    }
  end

  ip['reverse'] = body['reverse']
  ip['server'] = server

  if server
    server['public_ip'] = {
      'dynamic' => false,
      'id' => ip['id'],
      'address' => ip['address']
    }
  end

  response(status: 200, body: { 'ip' => ip })
end
update_security_group(security_group_id, body) click to toggle source
# File lib/fog/scaleway/requests/compute/update_security_group.rb, line 11
def update_security_group(security_group_id, body)
  body = jsonify(body)

  security_group = lookup(:security_groups, security_group_id)

  if body['organization_default'] && default_security_group
    raise_conflict('Cannot have more than one organization default group')
  end

  security_group['description'] = body['description']
  security_group['enable_default_security'] = body['enable_default_security']
  security_group['name'] = body['name']

  response(status: 200, body: { 'security_group' => security_group })
end
update_security_group_rule(security_group_id, rule_id, body) click to toggle source
# File lib/fog/scaleway/requests/compute/update_security_group_rule.rb, line 11
def update_security_group_rule(security_group_id, rule_id, body)
  body = jsonify(body)

  security_group = lookup(:security_groups, security_group_id)

  rule = data[:security_group_rules][security_group['id']][rule_id]

  raise_unknown_resource(rule_id) unless rule

  rule['action'] = body['action']
  rule['dest_port_from'] = body['dest_port_from']
  rule['direction'] = body['direction']
  rule['ip_range'] = body['ip_range']
  rule['protocol'] = body['protocol']

  response(status: 201, body: { 'rule' => rule })
end
update_server(server_id, body) click to toggle source
# File lib/fog/scaleway/requests/compute/update_server.rb, line 11
def update_server(server_id, body)
  body = jsonify(body)

  server = lookup(:servers, server_id)

  bootscript = if body['bootscript'].is_a?(Hash)
                 lookup(:bootscripts, body['bootscript']['id'])
               elsif body['bootscript'].is_a?(String)
                 lookup(:bootscripts, body['bootscript'])
               end

  _, product_server = lookup_product_server(server['commercial_type'])

  if body['enable_ipv6'] && !product_server['network']['ipv6_support']
    raise_invalid_request_error("Cannot enable ipv6 on #{commercial_type}")
  end

  volumes = {}
  body['volumes'].each do |index, volume|
    volume = lookup(:volumes, volume['id'])

    if volume['server'] && volume['server']['id'] != server['id']
      message = "volume #{volume['id']} is already attached to a server"
      raise_invalid_request_error(message)
    end

    volumes[index] = volume
  end

  server['bootscript'] = bootscript if bootscript
  server['dynamic_ip_required'] = body['dynamic_ip_required']
  server['enable_ipv6'] = body['enable_ipv6']
  server['hostname'] = body['name']
  server['modification_date'] = now
  server['name'] = body['name']
  server['tags'] = body['tags']
  server['volumes'] = volumes

  if server['dynamic_ip_required'] && server['state'] == 'running'
    server['public_ip'] ||= create_dynamic_ip
  elsif !server['dynamic_ip_required'] && server['public_ip'] && server['public_ip']['dynamic']
    server['public_ip'] = nil
  end

  if server['enable_ipv6'] && server['state'] == 'running'
    server['ipv6'] ||= create_ipv6
  elsif !server['enable_ipv6']
    server['ipv6'] = nil
  end

  data[:volumes].each do |id, volume|
    if server['volumes'].any? { |_i, v| v['id'] == id }
      volume['server'] = {
        'id' => server['id'],
        'name' => server['name']
      }
    elsif volume['server'] && volume['server']['id'] == server['id']
      volume['server'] = nil
    end
  end

  response(status: 200, body: { 'server' => server })
end
update_snapshot(snapshot_id, body) click to toggle source
# File lib/fog/scaleway/requests/compute/update_snapshot.rb, line 11
def update_snapshot(snapshot_id, body)
  body = jsonify(body)

  snapshot = lookup(:snapshots, snapshot_id)

  snapshot['modification_date'] = now
  snapshot['name'] = body['name']

  response(status: 200, body: { 'snapshot' => snapshot })
end
update_user_data(server_id, key, value) click to toggle source
# File lib/fog/scaleway/requests/compute/update_user_data.rb, line 15
def update_user_data(server_id, key, value)
  server = lookup(:servers, server_id)

  data[:user_data][server['id']][key] = value

  response(status: 204)
end
update_volume(volume_id, body) click to toggle source
# File lib/fog/scaleway/requests/compute/update_volume.rb, line 11
def update_volume(volume_id, body)
  body = jsonify(body)

  volume = lookup(:volumes, volume_id)

  volume['modification_date'] = now
  volume['name'] = body['name']

  response(status: 200, body: { 'volume' => volume })
end

Private Instance Methods

create_default_security_group() click to toggle source
# File lib/fog/scaleway/compute.rb, line 307
def create_default_security_group
  name = 'Default security group'
  options = {
    description: 'Auto generated security group.',
    organization_default: true
  }

  create_security_group(name, options).body['security_group']
end
create_dynamic_ip() click to toggle source
# File lib/fog/scaleway/compute.rb, line 317
def create_dynamic_ip
  {
    'dynamic' => true,
    'id' => Fog::UUID.uuid,
    'address' => Fog::Mock.random_ip
  }
end
create_ipv6() click to toggle source
# File lib/fog/scaleway/compute.rb, line 325
def create_ipv6
  {
    'netmask' => '127',
    'gateway' => random_ipv6.mask(127).to_s,
    'address' => random_ipv6.mask(127).succ.to_s
  }
end
data() click to toggle source
# File lib/fog/scaleway/compute.rb, line 291
def data
  self.class.data[@token]
end
decode_body(response) click to toggle source
# File lib/fog/scaleway/compute.rb, line 371
def decode_body(response)
  body         = response.body
  content_type = response.headers['Content-Type']

  if !body.nil? && !body.empty? && content_type =~ %r{application/json.*}i
    Fog::JSON.decode(body)
  else
    body
  end
end
default_security_group() click to toggle source
# File lib/fog/scaleway/compute.rb, line 303
def default_security_group
  data[:security_groups].values.find { |s| s['organization_default'] }
end
encode_body(params) click to toggle source
# File lib/fog/scaleway/compute.rb, line 358
def encode_body(params)
  body         = params[:body]
  content_type = params[:headers]['Content-Type']

  if body.nil? || body.is_a?(String)
    body
  elsif content_type =~ %r{application/json.*}i
    Fog::JSON.encode(body)
  else
    body.to_s
  end
end
jsonify(value) click to toggle source
# File lib/fog/scaleway/compute.rb, line 398
def jsonify(value)
  Fog::JSON.decode(Fog::JSON.encode(value))
end
lookup(type, id) click to toggle source
# File lib/fog/scaleway/compute.rb, line 295
def lookup(type, id)
  data[type][id] || raise_unknown_resource(id)
end
lookup_product_server(name) click to toggle source
# File lib/fog/scaleway/compute.rb, line 299
def lookup_product_server(name)
  PRODUCTS['servers'].find { |n, s| n == name || s['alt_names'].include?(name) }
end
now() click to toggle source
# File lib/fog/scaleway/compute.rb, line 394
def now
  Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S.%6N%:z')
end
raise_conflict(message) click to toggle source
# File lib/fog/scaleway/compute.rb, line 390
def raise_conflict(message)
  raise Fog::Scaleway::Compute::Conflict, message
end
raise_invalid_request_error(message) click to toggle source
# File lib/fog/scaleway/compute.rb, line 382
def raise_invalid_request_error(message)
  raise Fog::Scaleway::Compute::InvalidRequestError, message
end
raise_unknown_resource(id) click to toggle source
# File lib/fog/scaleway/compute.rb, line 386
def raise_unknown_resource(id)
  raise Fog::Scaleway::Compute::UnknownResource, "\"#{id}\" not found"
end
random_ipv6() click to toggle source
# File lib/fog/scaleway/compute.rb, line 402
def random_ipv6
  IPAddr.new(1 + rand((2**128) - 1), Socket::AF_INET6)
end
response(params) click to toggle source
# File lib/fog/scaleway/compute.rb, line 345
def response(params)
  params[:headers] ||= {}
  params[:headers]['Content-Type'] ||= 'application/json'

  params[:body] = encode_body(params)

  response = Excon::Response.new(params)

  response.body = decode_body(response)

  response
end
terminate_server(server) click to toggle source
# File lib/fog/scaleway/compute.rb, line 333
def terminate_server(server)
  data[:servers].delete(server['id'])

  security_group = lookup(:security_groups, server['security_group']['id'])
  security_group['servers'].reject! { |s| s['id'] == server['id'] }

  server['volumes'].each_value do |volume|
    volume['server'] = nil
    delete_volume(volume['id'])
  end
end