class Fog::AWS::DNS::Mock

Constants

SET_PREFIX

Public Class Methods

data() click to toggle source
# File lib/fog/aws/dns.rb, line 32
def self.data
  @data ||= Hash.new do |hash, region|
    hash[region] = Hash.new do |region_hash, key|
      region_hash[key] = {
        :buckets => {},
        :limits => {
          :duplicate_domains => 5
        },
        :zones => {},
        :changes => {}
      }
    end
  end
end
new(options={}) click to toggle source
# File lib/fog/aws/dns.rb, line 51
def initialize(options={})
  @use_iam_profile = options[:use_iam_profile]
  setup_credentials(options)
  @region             = options[:region]
end
reset() click to toggle source
# File lib/fog/aws/dns.rb, line 47
def self.reset
  @data = nil
end

Public Instance Methods

change_resource_record_sets(zone_id, change_batch, options = {}) click to toggle source
# File lib/fog/aws/requests/dns/change_resource_record_sets.rb, line 92
def change_resource_record_sets(zone_id, change_batch, options = {})
  response = Excon::Response.new
  errors   = []


  if (zone = self.data[:zones][zone_id])
    response.status = 200

    change_id = Fog::AWS::Mock.change_id
    change_batch.each do |change|

      change_name = change[:name]
      change_name = change_name + "." unless change_name.end_with?(".")

      case change[:action]
      when "CREATE"
        if zone[:records][change[:type]].nil?
          zone[:records][change[:type]] = {}
        end

        if !record_exist?(zone, change, change_name)
          # raise change.to_s if change[:resource_records].nil?
          new_record =
            if change[:alias_target]
              record = {
                :alias_target => change[:alias_target]
              }
            else
              record = {
                :ttl => change[:ttl].to_s,
              }
            end

          new_record = {
            :change_id        => change_id,
            :resource_records => change[:resource_records] || [],
            :name             => change_name,
            :type             => change[:type],
            :set_identifier   => change[:set_identifier],
            :weight           => change[:weight]
          }.merge(record)

          if change[:set_identifier].nil?
            zone[:records][change[:type]][change_name] = new_record
          else
            zone[:records][change[:type]][change_name] = {} if zone[:records][change[:type]][change_name].nil?
            zone[:records][change[:type]][change_name][SET_PREFIX + change[:set_identifier]] = new_record
          end
        else
          errors << "Tried to create resource record set #{change[:name]}. type #{change[:type]}, but it already exists"
        end
      when "DELETE"
        action_performed = false
        if !zone[:records][change[:type]].nil? && !zone[:records][change[:type]][change_name].nil? && !change[:set_identifier].nil?
          action_performed = true unless zone[:records][change[:type]][change_name].delete(SET_PREFIX + change[:set_identifier]).nil?
          zone[:records][change[:type]].delete(change_name) if zone[:records][change[:type]][change_name].empty?
        elsif !zone[:records][change[:type]].nil?
          action_performed = true unless zone[:records][change[:type]].delete(change_name).nil?
        end

        if !action_performed
          errors << "Tried to delete resource record set #{change[:name]}. type #{change[:type]}, but it was not found"
        end
      end
    end

    if errors.empty?
      change = {
        :id           => change_id,
        :status       => 'PENDING',
        :submitted_at => Time.now.utc.iso8601
      }
      self.data[:changes][change[:id]] = change
      response.body = {
        'Id'          => change[:id],
        'Status'      => change[:status],
        'SubmittedAt' => change[:submitted_at]
      }
      response
    else
      raise Fog::AWS::DNS::Error.new("InvalidChangeBatch => #{errors.join(", ")}")
    end
  else
    raise Fog::AWS::DNS::NotFound.new("NoSuchHostedZone => A hosted zone with the specified hosted zone ID does not exist.")
  end
end
create_hosted_zone(name, options = {}) click to toggle source
# File lib/fog/aws/requests/dns/create_hosted_zone.rb, line 62
def create_hosted_zone(name, options = {})
  # Append a trailing period to the name if absent.
  name = name + "." unless name.end_with?(".")

  response = Excon::Response.new
  if list_hosted_zones.body['HostedZones'].select {|z| z['Name'] == name}.size < self.data[:limits][:duplicate_domains]
    response.status = 201
    if options[:caller_ref]
      caller_ref = options[:caller_ref]
    else
      #make sure we have a unique call reference
      caller_ref = "ref-#{rand(1000000).to_s}"
    end
    zone_id = "/hostedzone/#{Fog::AWS::Mock.zone_id}"
    self.data[:zones][zone_id] = {
      :id => zone_id,
      :name => name,
      :reference => caller_ref,
      :comment => options[:comment],
      :records => {}
    }
    change = {
      :id => Fog::AWS::Mock.change_id,
      :status => 'PENDING',
      :submitted_at => Time.now.utc.iso8601
    }
    self.data[:changes][change[:id]] = change
    response.body = {
      'HostedZone' => {
        'Id' => zone_id,
        'Name' => name,
        'CallerReference' => caller_ref,
        'Comment' => options[:comment]
      },
      'ChangeInfo' => {
        'Id' => change[:id],
        'Status' => change[:status],
        'SubmittedAt' => change[:submitted_at]
      },
      'NameServers' => Fog::AWS::Mock.nameservers
    }
    response
  else
    raise Fog::AWS::DNS::Error.new("DelegationSetNotAvailable => Amazon Route 53 allows some duplication, but Amazon Route 53 has a maximum threshold of duplicated domains. This error is generated when you reach that threshold. In this case, the error indicates that too many hosted zones with the given domain name exist. If you want to create a hosted zone and Amazon Route 53 generates this error, contact Customer Support.")
  end
end
data() click to toggle source
# File lib/fog/aws/dns.rb, line 57
def data
  self.class.data[@region][@aws_access_key_id]
end
delete_hosted_zone(zone_id) click to toggle source
# File lib/fog/aws/requests/dns/delete_hosted_zone.rb, line 37
def delete_hosted_zone(zone_id)
  response = Excon::Response.new
  key = [zone_id, "/hostedzone/#{zone_id}"].find { |k| !self.data[:zones][k].nil? } ||
    raise(Fog::AWS::DNS::NotFound.new("NoSuchHostedZone => A hosted zone with the specified hosted zone does not exist."))

    change = {
      :id => Fog::AWS::Mock.change_id,
      :status => 'INSYNC',
      :submitted_at => Time.now.utc.iso8601
    }

    self.data[:changes][change[:id]] = change

    response.status = 200
    response.body = {
      'ChangeInfo' => {
        'Id' => change[:id],
        'Status' => change[:status],
        'SubmittedAt' => change[:submitted_at]
      }
    }
    self.data[:zones].delete(key)
    response
end
get_change(change_id) click to toggle source
# File lib/fog/aws/requests/dns/get_change.rb, line 34
def get_change(change_id)
  response = Excon::Response.new
  # find the record with matching change_id
  # records = data[:zones].values.map{|z| z[:records].values.map{|r| r.values}}.flatten
  change = self.data[:changes][change_id] ||
    raise(Fog::AWS::DNS::NotFound.new("NoSuchChange => Could not find resource with ID: #{change_id}"))

  response.status = 200
  submitted_at = Time.parse(change[:submitted_at])
  response.body = {
    'Id' => change[:id],
    # set as insync after some time
    'Status' => (submitted_at + Fog::Mock.delay) < Time.now ? 'INSYNC' : change[:status],
    'SubmittedAt' => change[:submitted_at]
  }
  response
end
get_hosted_zone(zone_id) click to toggle source
# File lib/fog/aws/requests/dns/get_hosted_zone.rb, line 39
def get_hosted_zone(zone_id)
  response = Excon::Response.new
  if (zone = self.data[:zones][zone_id])
    response.status = 200
    response.body = {
      'HostedZone' => {
        'Id' => zone[:id],
        'Name' => zone[:name],
        'CallerReference' => zone[:reference],
        'Comment' => zone[:comment]
      },
      'NameServers' => Fog::AWS::Mock.nameservers
    }
    response
  else
    raise Fog::AWS::DNS::NotFound.new("NoSuchHostedZone => A hosted zone with the specified hosted zone ID does not exist.")
  end
end
list_all_records(record, zone, name) click to toggle source
# File lib/fog/aws/requests/dns/list_resource_record_sets.rb, line 62
def list_all_records(record, zone, name)
  [].tap do |tmp_records|
    tmp_records.push(record) if !record[:name].nil? && ( name.nil? || record[:name].gsub(zone[:name],"") >= name)
    record.each do |key,subr|
      if subr.is_a?(Hash) && key.is_a?(String) &&
        key.start_with?(Fog::AWS::DNS::Mock::SET_PREFIX)
        if name.nil?
          tmp_records.append(subr)
        else
          tmp_records.append(subr) if !subr[:name].nil? && subr[:name].gsub(zone[:name],"") >= name
        end
      end
    end
  end
end
list_hosted_zones(options = {}) click to toggle source
# File lib/fog/aws/requests/dns/list_hosted_zones.rb, line 50
def list_hosted_zones(options = {})
  maxitems = [options[:max_items]||100,100].min

  if options[:marker].nil?
    start = 0
  else
    start = self.data[:zones].find_index {|z| z[:id] == options[:marker]}
  end

  zones     = self.data[:zones].values[start, maxitems]
  next_zone = self.data[:zones].values[start + maxitems]
  truncated = !next_zone.nil?

  response = Excon::Response.new
  response.status = 200
  response.body = {
    'HostedZones' => zones.map do |z|
      {
        'Id' => z[:id],
        'Name' => z[:name],
        'CallerReference' => z[:reference],
        'Comment' => z[:comment],
      }
    end,
    'Marker' => options[:marker].to_s,
    'MaxItems' => maxitems,
    'IsTruncated' => truncated
  }

  if truncated
    response.body['NextMarker'] = next_zone[:id]
  end

  response
end
list_resource_record_sets(zone_id, options = {}) click to toggle source
# File lib/fog/aws/requests/dns/list_resource_record_sets.rb, line 78
def list_resource_record_sets(zone_id, options = {})
  maxitems = [options[:max_items]||100,100].min

  response = Excon::Response.new

  zone = self.data[:zones][zone_id] ||
    raise(Fog::AWS::DNS::NotFound.new("NoSuchHostedZone => A hosted zone with the specified hosted zone ID does not exist."))

  records = if options[:type]
              records_type = zone[:records][options[:type]]
              records_type.values if records_type
            else
              zone[:records].values.map{|r| r.values}.flatten
            end

  records ||= []

  tmp_records = []
  if options[:name]
    name = options[:name].gsub(zone[:name],"")

    records.each do |r|
      tmp_records += list_all_records(r, zone, name)
    end
  else
    records.each do |r|
      tmp_records += list_all_records(r, zone, nil)
    end
  end
  records = tmp_records

  # sort for pagination
  records.sort! { |a,b| a[:name].gsub(zone[:name],"") <=> b[:name].gsub(zone[:name],"") }


  next_record  = records[maxitems]
  records      = records[0, maxitems]
  truncated    = !next_record.nil?

  response.status = 200
  response.body = {
    'ResourceRecordSets' => records.map do |r|
      if r[:alias_target]
        record = {
          'AliasTarget' => {
            'HostedZoneId' => r[:alias_target][:hosted_zone_id],
            'DNSName' => r[:alias_target][:dns_name]
          }
        }
      else
        record = {
          'TTL' => r[:ttl]
        }
      end
      {
        'ResourceRecords' => r[:resource_records],
        'Name' => r[:name],
        'Type' => r[:type],
        'SetIdentifier' => r[:set_identifier],
        'Weight' => r[:weight]
      }.merge(record)
    end,
    'MaxItems' => maxitems,
    'IsTruncated' => truncated
  }

  if truncated
    response.body['NextRecordName'] = next_record[:name]
    response.body['NextRecordType'] = next_record[:type]
  end

  response
end
record_exist?(zone,change,change_name) click to toggle source
# File lib/fog/aws/requests/dns/change_resource_record_sets.rb, line 80
def record_exist?(zone,change,change_name)
  return false if zone[:records][change[:type]].nil?
  current_records = zone[:records][change[:type]][change_name]
  return false if current_records.nil?

  if !change[:set_identifier].empty?
    !current_records[change[:SetIdentifier]].nil?
  else
    !current_records.empty?
  end
end
reset_data() click to toggle source
# File lib/fog/aws/dns.rb, line 61
def reset_data
  self.class.data[@region].delete(@aws_access_key_id)
end
setup_credentials(options) click to toggle source
# File lib/fog/aws/dns.rb, line 69
def setup_credentials(options)
  @aws_access_key_id  = options[:aws_access_key_id]
end
signature(params) click to toggle source
# File lib/fog/aws/dns.rb, line 65
def signature(params)
  "foo"
end