/
client.rb
109 lines (86 loc) · 2.59 KB
/
client.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
63
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
require 'roadworker/string-ext'
require 'roadworker/dsl'
require 'roadworker/log'
require 'roadworker/route53-wrapper'
require 'logger'
require 'ostruct'
module Roadworker
class Client
include Roadworker::Log
def initialize(options = {})
@options = OpenStruct.new(options)
@options.logger ||= Logger.new($stdout)
String.colorize = @options.color
@options.route53 = AWS::Route53.new
@route53 = Route53Wrapper.new(@options)
end
def apply(file)
dsl = nil
if file.kind_of?(String)
open(file) do |f|
dsl = DSL.define(f.read, file).result
end
else
dsl = DSL.define(file.read, file.path).result
end
updated = false
if dsl.hosted_zones.empty? and not @options.force
log(:warn, "Nothing is defined (pass `--force` if you want to remove)", :yellow)
else
AWS.memoize {
walk_hosted_zones(dsl)
updated = @options.updated
}
end
return updated
end
def export
exported = AWS.memoize { @route53.export }
DSL.convert(exported)
end
private
def walk_hosted_zones(dsl)
expected = collection_to_hash(dsl.hosted_zones, :name)
actual = collection_to_hash(@route53.hosted_zones, :name)
expected.each do |keys, expected_zone|
name = keys[0]
actual_zone = actual.delete(keys) || @route53.hosted_zones.create(name)
walk_rrsets(expected_zone, actual_zone)
end
actual.each do |keys, zone|
zone.rrsets.each do |record|
record.delete(:cascaded => true)
end
zone.delete
end
end
def walk_rrsets(expected_zone, actual_zone)
expected = collection_to_hash(expected_zone.rrsets, :name, :type, :set_identifier)
actual = collection_to_hash(actual_zone.rrsets, :name, :type, :set_identifier)
expected.each do |keys, expected_record|
name = keys[0]
type = keys[1]
set_identifier = keys[2]
actual_record = actual.delete(keys)
if actual_record
unless actual_record.eql?(expected_record)
actual_record.update(expected_record)
end
else
actual_record = actual_zone.rrsets.create(name, type, expected_record)
end
end
actual.each do |keys, record|
record.delete
end
end
def collection_to_hash(collection, *keys)
hash = {}
collection.each do |item|
key_list = keys.map {|k| item.send(k) }
hash[key_list] = item
end
return hash
end
end # Client
end # Roadworker