Class: DNS::Zone

Inherits:
Object
  • Object
show all
Defined in:
lib/dns/zone.rb,
lib/dns/zone/rr.rb,
lib/dns/zone/version.rb

Overview

Represents a ‘whole’ zone of many resource records (RRs).

This is also the primary namespace for the ‘dns-zone` gem.

Defined Under Namespace

Modules: RR Classes: TestCase

Constant Summary collapse

Version =

Version number (major.minor.tiny)

'0.1.2'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeZone

Returns a new instance of Zone.



14
15
16
# File 'lib/dns/zone.rb', line 14

def initialize
  @records = []
end

Instance Attribute Details

#originObject

Returns the value of attribute origin.



12
13
14
# File 'lib/dns/zone.rb', line 12

def origin
  @origin
end

#recordsObject

Returns the value of attribute records.



12
13
14
# File 'lib/dns/zone.rb', line 12

def records
  @records
end

#ttlObject

Returns the value of attribute ttl.



12
13
14
# File 'lib/dns/zone.rb', line 12

def ttl
  @ttl
end

Class Method Details

.extract_entries(string) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/dns/zone.rb', line 64

def self.extract_entries(string)
  entries = []
  mode = :line
  entry = ''

  parentheses_ref_count = 0

  string.lines.each do |line|
    # strip comments unless escaped
    line = line.gsub(/(?<!\\);.*/o, '').chomp

    next if line.gsub(/\s+/, '').empty?

    # append to entry line
    entry << line

    quotes = entry.count('"')
    has_quotes = quotes > 0

    parentheses = entry.count('()')
    has_parentheses = parentheses > 0

    if has_quotes
      character_strings = entry.scan(/("(?:[^"\\]+|\\.)*")/).join(' ')
      without = entry.gsub(/"((?:[^"\\]+|\\.)*)"/, '')
      parentheses_ref_count = without.count('(') - without.count(')')
    else
      parentheses_ref_count = entry.count('(') - entry.count(')')
    end

    # are parentheses balanced?
    if parentheses_ref_count == 0
      if has_quotes
        without.gsub!(/[()]/, '')
        without.gsub!(/[ ]{2,}/, '  ')
        #entries << (without + character_strings)
        entry = (without + character_strings)
      else
        entry.gsub!(/[()]/, '')
        entry.gsub!(/[ ]{2,}/, '  ')
        entry.gsub!(/[ ]+$/, '')
        #entries << entry
      end
      entries << entry
      entry = ''
    end

  end

  return entries
end

.load(string) ⇒ Object

FROM RFC:

The format of these files is a sequence of entries.  Entries are
predominantly line-oriented, though parentheses can be used to continue
a list of items across a line boundary, and text literals can contain
CRLF within the text.  Any combination of tabs and spaces act as a
delimiter between the separate items that make up an entry.  The end of
any line in the master file can end with a comment.  The comment starts
with a ";" (semicolon).


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/dns/zone.rb', line 36

def self.load(string)
  # get entries
  entries = self.extract_entries(string)

  instance = self.new

  options = {}
  entries.each do |entry|
    if entry =~ /\$(ORIGIN|TTL)\s+(.+)/
      instance.ttl    = $2 if $1 == 'TTL'
      instance.origin = $2 if $1 == 'ORIGIN'
      next
    end

    if entry =~ DNS::Zone::RR::REGEX_RR
      rec = DNS::Zone::RR.load(entry, options)
      next unless rec
      instance.records << rec
      options[:last_label] = rec.label
    end

  end

  # read in special statments like $TTL and $ORIGIN
  # parse each RR and create a Ruby object for it
  return instance
end

Instance Method Details

#dumpObject



18
19
20
21
22
23
24
25
# File 'lib/dns/zone.rb', line 18

def dump
  content = []
  @records.each do |rr|
    content << rr.dump
  end

  content.join("\n") << "\n"
end