class DNS::Zone::RR::Record

Parent class of all RR types, common resource record code lives here. Is responsible for building a Ruby object given a RR string.

@abstract Each RR TYPE should subclass and override: {#load} and #{dump}

Attributes

klass[R]
label[RW]
ttl[RW]

Public Class Methods

new() click to toggle source
# File lib/dns/zone/rr/record.rb, line 10
def initialize
  @label = '@'
  @klass = 'IN'
end

Public Instance Methods

dump() click to toggle source

Build RR zone file output.

@return [String] RR zone file output

# File lib/dns/zone/rr/record.rb, line 46
def dump
  general_prefix.join(' ')
end
general_prefix() click to toggle source

Returns 'general' prefix (in parts) that come before the RDATA. Used by all RR types, generates: `[<label>] [<ttl>] [<class>] <type>`

@return [Array<String>] rr prefix parts

# File lib/dns/zone/rr/record.rb, line 34
def general_prefix
  parts = []
  parts << label
  parts << ttl if ttl
  parts << 'IN'
  parts << type
  parts
end
load(string, options = {}) click to toggle source

@abstract Override to update instance with RR type spesific data. @param string [String] RR ASCII string data @param options [Hash] additional data required to correctly parse a 'whole' zone @option options [String] :last_label The last label used by the previous RR @return [Object]

# File lib/dns/zone/rr/record.rb, line 55
def load(string, options = {})
  raise NotImplementedError, "#load method must be implemented by subclass (#{self.class})"
end
load_general_and_get_rdata(string, options = {}) click to toggle source

Load 'general' RR data/params and return the remaining RDATA for further parsing.

@param string [String] RR ASCII string data @param options [Hash] additional data required to correctly parse a 'whole' zone @return [String] remaining RDATA

# File lib/dns/zone/rr/record.rb, line 64
def load_general_and_get_rdata(string, options = {})
  # strip comments, unless its escaped.
  # skip semicolons within "quote segments" (TXT records)
  string.gsub!(/((?<!\\);)(?=(?:[^"]|"[^"]*")*$).*/o, "")

  captures = string.match(DNS::Zone::RR::REGEX_RR)
  return nil unless captures

  if [' ', nil].include?(captures[:label])
    @label = options[:last_label]
  else
    @label = captures[:label]
  end

  # unroll records nested under other origins
  unrolled_origin = options[:last_origin].sub(options[:origin], '').chomp('.') if options[:last_origin]
  if unrolled_origin && !unrolled_origin.empty?
    @label = @label == '@' ? unrolled_origin : "#{@label}.#{unrolled_origin}"
  end

  @ttl = captures[:ttl]
  captures[:rdata]
end
type() click to toggle source

FIXME: should we just: `def type; 'SOA'; end` rather then do the class name convension?

Figures out TYPE of RR using class name. This means the class name must match the RR ASCII TYPE.

When called directly on the parent class (that you should never do), it will

return the string as `<type>`, for use with internal tests.

@return [String] the RR type

# File lib/dns/zone/rr/record.rb, line 24
def type
  name = self.class.name.split('::').last
  return '<type>' if name == 'Record'
  name
end