Class: Dev::Dns::Resource

Inherits:
Object show all
Defined in:
lib/firespring_dev_commands/dns/resource.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(domain) ⇒ Resource

Returns a new instance of Resource.



6
7
8
# File 'lib/firespring_dev_commands/dns/resource.rb', line 6

def initialize(domain)
  @domain = domain
end

Instance Attribute Details

#domainObject (readonly)

Returns the value of attribute domain.



4
5
6
# File 'lib/firespring_dev_commands/dns/resource.rb', line 4

def domain
  @domain
end

Class Method Details

.ip?(value) ⇒ Boolean

Returns whether or not the given value is a valid IPv4 or IPv6 address

Returns:

  • (Boolean)


11
12
13
# File 'lib/firespring_dev_commands/dns/resource.rb', line 11

def self.ip?(value)
  ipv4?(value) || ipv6?(value)
end

.ipv4?(value) ⇒ Boolean

Returns whether or not the given value is a valid IPv4 address

Returns:

  • (Boolean)


16
17
18
# File 'lib/firespring_dev_commands/dns/resource.rb', line 16

def self.ipv4?(value)
  value.match?(Resolv::IPv4::Regex)
end

.ipv6?(value) ⇒ Boolean

Returns whether or not the given value is a valid IPv6 address

Returns:

  • (Boolean)


21
22
23
# File 'lib/firespring_dev_commands/dns/resource.rb', line 21

def self.ipv6?(value)
  value.match?(Resolv::IPv6::Regex)
end

Instance Method Details

#lookup(name = domain, type: Resolv::DNS::Resource::IN::A) ⇒ Object

Lookup the given name using the record type provided.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/firespring_dev_commands/dns/resource.rb', line 57

def lookup(name = domain, type: Resolv::DNS::Resource::IN::A)
  # Validate the type
  raise 'lookup type must be a Resolv::DNS::Resource' unless type.ancestors.include?(Resolv::DNS::Resource)

  # If we were given a tld, return empty
  return [] unless name.include?('.')

  # Look up NS records for the given host
  records = Resolv::DNS.new.getresources(name, type)

  # Return the record names
  records.map do |record|
    if record.respond_to?(:address)
      record.address.to_s
    elsif record.respond_to?(:name)
      record.name.to_s
    else
      ''
    end
  end
rescue
  sleep(1)
  retry
end

#recursive_a_lookup(name = domain) ⇒ Object

Recursively attempt to find an A record for the given domain. If one isn’t found, also check for CNAMEs continually until we have either found an IP or run out of things to check



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/firespring_dev_commands/dns/resource.rb', line 39

def recursive_a_lookup(name = domain)
  # Try looking up an A record first. If we find one, we are done.
  records = lookup(name, type: Resolv::DNS::Resource::IN::A)
  return records unless records.empty?

  # Try looking up a CNAME record
  records = lookup(name, type: Resolv::DNS::Resource::IN::CNAME)

  # If we didn't find an A record _or_ a CNAME, just return empty
  return records if records.empty?

  # If we found more than one CNAME that is a DNS error
  raise "Found more than one CNAME entry for #{name}. This is not allowed by DNS" if records.length > 1

  recursive_a_lookup(records.first)
end

#recursive_nameserver_lookup(name = domain) ⇒ Object

Recursively determine the correct nameservers for the given domain. If nameservers are not found, strip subdomains off until we’ve reached the TLD



27
28
29
30
31
32
33
34
35
# File 'lib/firespring_dev_commands/dns/resource.rb', line 27

def recursive_nameserver_lookup(name = domain)
  records = lookup(name, type: Resolv::DNS::Resource::IN::NS)

  # Strip the subdomain and try again if we didn't find any nameservers (this can happen with wildcards)
  return recursive_nameserver_lookup(name.split('.', 2).last) if records.empty?

  # Look up the IPs for the nameservers
  records
end