Class: Zonesync::Manifest

Inherits:
Struct
  • Object
show all
Defined in:
lib/zonesync/manifest.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#recordsObject

Returns the value of attribute records

Returns:

  • (Object)

    the current value of records



10
11
12
# File 'lib/zonesync/manifest.rb', line 10

def records
  @records
end

#zoneObject

Returns the value of attribute zone

Returns:

  • (Object)

    the current value of zone



10
11
12
# File 'lib/zonesync/manifest.rb', line 10

def zone
  @zone
end

Instance Method Details

#diffable?(record) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
# File 'lib/zonesync/manifest.rb', line 50

def diffable?(record)
  if existing?
    matches?(record)
  else
    DIFFABLE_RECORD_TYPES.include?(record.type)
  end
end

#existingObject



11
12
13
# File 'lib/zonesync/manifest.rb', line 11

def existing
  records.find(&:manifest?)
end

#existing?Boolean

Returns:

  • (Boolean)


15
16
17
# File 'lib/zonesync/manifest.rb', line 15

def existing?
  !!existing
end

#existing_checksumObject



23
24
25
# File 'lib/zonesync/manifest.rb', line 23

def existing_checksum
  records.find(&:checksum?)
end

#generateObject



19
20
21
# File 'lib/zonesync/manifest.rb', line 19

def generate
  generate_v2
end

#generate_checksumObject



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/zonesync/manifest.rb', line 27

def generate_checksum
  input_string = diffable_records.map(&:to_s).join
  sha256 = Digest::SHA256.hexdigest(input_string)
  Record.new(
    name: "zonesync_checksum.#{zone.origin}",
    type: "TXT",
    ttl: 3600,
    rdata: sha256.inspect,
    comment: nil,
  )
end

#generate_v2Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/zonesync/manifest.rb', line 39

def generate_v2
  hashes = diffable_records.map { |record| RecordHash.generate(record) }
  Record.new(
    name: "zonesync_manifest.#{zone.origin}",
    type: "TXT",
    ttl: 3600,
    rdata: hashes.join(',').inspect,
    comment: nil,
  )
end

#matches?(record) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/zonesync/manifest.rb', line 70

def matches?(record)
  return false unless existing?
  manifest_data = existing.rdata[1..-2] # remove quotes

  # Check if this is v2 format (comma-separated hashes) or v1 format (type:names)
  if manifest_data.include?(";")
    # V1 format: "A:@,mail;CNAME:www;MX:@ 10,@ 20"
    hash = manifest_data
      .split(";")
      .reduce({}) do |hash, pair|
        type, short_names = pair.split(":")
        hash[type] = short_names.split(",")
        hash
      end
    shorthands = hash.fetch(record.type, [])
    shorthands.include?(shorthand_for(record))
  else
    # V2 format: "1r81el0,60oib3,ky0g92,9pp0kg"
    expected_hashes = manifest_data.split(",")
    record_hash = RecordHash.generate(record)
    expected_hashes.include?(record_hash)
  end
end

#shorthand_for(record, with_type: false) ⇒ Object



94
95
96
97
98
99
100
101
# File 'lib/zonesync/manifest.rb', line 94

def shorthand_for(record, with_type: false)
  shorthand = record.short_name(zone.origin)
  shorthand = "#{record.type}:#{shorthand}" if with_type
  if record.type == "MX"
    shorthand += " #{record.rdata[/^\d+/]}"
  end
  shorthand
end

#v1_format?Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
# File 'lib/zonesync/manifest.rb', line 58

def v1_format?
  return false unless existing?
  manifest_data = existing.rdata[1..-2]
  # V1 format uses "TYPE:" syntax, v2 uses comma-separated hashes
  manifest_data.include?(":") || manifest_data.include?(";")
end

#v2_format?Boolean

Returns:

  • (Boolean)


65
66
67
68
# File 'lib/zonesync/manifest.rb', line 65

def v2_format?
  return false unless existing?
  !v1_format?
end