roadworker 0.4.12 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +15 -0
- data/bin/roadwork +21 -18
- data/lib/roadworker/client.rb +36 -1
- data/lib/roadworker/dsl-converter.rb +14 -1
- data/lib/roadworker/dsl.rb +21 -2
- data/lib/roadworker/route53-exporter.rb +6 -1
- data/lib/roadworker/route53-ext.rb +39 -1
- data/lib/roadworker/route53-wrapper.rb +45 -5
- data/lib/roadworker/version.rb +1 -3
- metadata +11 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc7cfa6e280e4ea6a6c8681638c62f850bd060cb
|
4
|
+
data.tar.gz: 1759745736aaa13e12da2bfd7f3ca2dba5ed8b3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4690314969ec784a429bdb766894977e27a889daea3222e992897a19c699af1f150683459590457293f27b359ef936190063a83ce1fde7226e17b2bde01fffd5
|
7
|
+
data.tar.gz: 3281f25cf906fdcbb76db28d4af50202b2ec715d4f42ad3b28977fa8ff6ec78cee45a6d6e04ad2d90bf2a60b3d9d0576260e2a692a5762d13661d7a75e93e883
|
data/README.md
CHANGED
@@ -58,6 +58,7 @@ Usage: roadwork [options]
|
|
58
58
|
-t, --test
|
59
59
|
--nameservers SERVERS
|
60
60
|
--port PORT
|
61
|
+
--target-zone REGEXP
|
61
62
|
--no-color
|
62
63
|
--debug
|
63
64
|
```
|
@@ -118,6 +119,20 @@ hosted_zone "info.winebarrel.jp." do
|
|
118
119
|
)
|
119
120
|
end
|
120
121
|
end
|
122
|
+
|
123
|
+
# Private HostedZone
|
124
|
+
hosted_zone "winebarrel.local." do
|
125
|
+
vpc "us-east-1", "vpc-xxxxxxxx"
|
126
|
+
vpc "us-east-2", "vpc-xxxxxxxx"
|
127
|
+
|
128
|
+
rrset "winebarrel.local.", "A" do
|
129
|
+
ttl 300
|
130
|
+
resource_records(
|
131
|
+
"10.0.0.1",
|
132
|
+
"10.0.0.2"
|
133
|
+
)
|
134
|
+
end
|
135
|
+
end
|
121
136
|
```
|
122
137
|
|
123
138
|
## Test
|
data/bin/roadwork
CHANGED
@@ -5,6 +5,8 @@ require 'roadworker'
|
|
5
5
|
require 'optparse'
|
6
6
|
require 'logger'
|
7
7
|
|
8
|
+
Version = Roadworker::VERSION
|
9
|
+
|
8
10
|
mode = nil
|
9
11
|
file = 'Routefile'
|
10
12
|
output_file = '-'
|
@@ -32,24 +34,25 @@ ARGV.options do |opt|
|
|
32
34
|
profile_name = nil
|
33
35
|
credentials_path = nil
|
34
36
|
|
35
|
-
opt.on('-p', '--profile PROFILE_NAME') {|v| profile_name = v
|
36
|
-
opt.on('' , '--credentials-path PATH') {|v| credentials_path = v
|
37
|
-
opt.on('-k', '--access-key ACCESS_KEY') {|v| access_key = v
|
38
|
-
opt.on('-s', '--secret-key SECRET_KEY') {|v| secret_key = v
|
39
|
-
opt.on('-a', '--apply') { mode = :apply
|
40
|
-
opt.on('-f', '--file FILE') {|v| file = v
|
41
|
-
opt.on('', '--dry-run') { options[:dry_run] = true
|
42
|
-
opt.on('' , '--force') { options[:force] = true
|
43
|
-
opt.on('', '--no-health-check-gc') { options[:no_health_check_gc] = true
|
44
|
-
opt.on('-e', '--export') { mode = :export
|
45
|
-
opt.on('-o', '--output FILE') {|v| output_file = v
|
46
|
-
opt.on('', '--split') { split = true
|
47
|
-
opt.on('', '--with-soa-ns') { options[:with_soa_ns] = true
|
48
|
-
opt.on('-t', '--test') { mode = :test
|
49
|
-
opt.on('' , '--nameservers SERVERS', Array) {|v| options[:nameservers] = v
|
50
|
-
opt.on('' , '--port PORT', Integer) {|v| options[:port] = v
|
51
|
-
opt.on('' , '--
|
52
|
-
opt.on('' , '--
|
37
|
+
opt.on('-p', '--profile PROFILE_NAME') {|v| profile_name = v }
|
38
|
+
opt.on('' , '--credentials-path PATH') {|v| credentials_path = v }
|
39
|
+
opt.on('-k', '--access-key ACCESS_KEY') {|v| access_key = v }
|
40
|
+
opt.on('-s', '--secret-key SECRET_KEY') {|v| secret_key = v }
|
41
|
+
opt.on('-a', '--apply') { mode = :apply }
|
42
|
+
opt.on('-f', '--file FILE') {|v| file = v }
|
43
|
+
opt.on('', '--dry-run') { options[:dry_run] = true }
|
44
|
+
opt.on('' , '--force') { options[:force] = true }
|
45
|
+
opt.on('', '--no-health-check-gc') { options[:no_health_check_gc] = true }
|
46
|
+
opt.on('-e', '--export') { mode = :export }
|
47
|
+
opt.on('-o', '--output FILE') {|v| output_file = v }
|
48
|
+
opt.on('', '--split') { split = true }
|
49
|
+
opt.on('', '--with-soa-ns') { options[:with_soa_ns] = true }
|
50
|
+
opt.on('-t', '--test') { mode = :test }
|
51
|
+
opt.on('' , '--nameservers SERVERS', Array) {|v| options[:nameservers] = v }
|
52
|
+
opt.on('' , '--port PORT', Integer) {|v| options[:port] = v }
|
53
|
+
opt.on('' , '--target-zone REGEXP') {|v| options[:target_zone] = Regexp.new(v) }
|
54
|
+
opt.on('' , '--no-color') { options[:color] = false }
|
55
|
+
opt.on('' , '--debug') { options[:debug] = true }
|
53
56
|
opt.parse!
|
54
57
|
|
55
58
|
aws_opts = {}
|
data/lib/roadworker/client.rb
CHANGED
@@ -77,15 +77,50 @@ module Roadworker
|
|
77
77
|
|
78
78
|
expected.each do |keys, expected_zone|
|
79
79
|
name = keys[0]
|
80
|
-
|
80
|
+
|
81
|
+
if @options.target_zone
|
82
|
+
next unless name =~ @options.target_zone
|
83
|
+
end
|
84
|
+
|
85
|
+
actual_zone = actual.delete(keys) || @route53.hosted_zones.create(name, :vpc => expected_zone.vpcs.first)
|
86
|
+
walk_vpcs(expected_zone, actual_zone)
|
81
87
|
walk_rrsets(expected_zone, actual_zone)
|
82
88
|
end
|
83
89
|
|
84
90
|
actual.each do |keys, zone|
|
91
|
+
name = keys[0]
|
92
|
+
|
93
|
+
if @options.target_zone
|
94
|
+
next unless name =~ @options.target_zone
|
95
|
+
end
|
96
|
+
|
85
97
|
zone.delete
|
86
98
|
end
|
87
99
|
end
|
88
100
|
|
101
|
+
def walk_vpcs(expected_zone, actual_zone)
|
102
|
+
expected_vpcs = expected_zone.vpcs || []
|
103
|
+
actual_vpcs = actual_zone.vpcs || []
|
104
|
+
|
105
|
+
if not expected_vpcs.empty? and actual_vpcs.empty?
|
106
|
+
log(:warn, "Cannot associate VPC to public zone", :yellow, expected_zone.name)
|
107
|
+
else
|
108
|
+
(expected_vpcs - actual_vpcs).each do |vpc|
|
109
|
+
actual_zone.associate_vpc(vpc)
|
110
|
+
end
|
111
|
+
|
112
|
+
unexpected_vpcs = actual_vpcs - expected_vpcs
|
113
|
+
|
114
|
+
if unexpected_vpcs.length.nonzero? and actual_vpcs.length - unexpected_vpcs.length < 1
|
115
|
+
log(:warn, "Private zone requires one or more of VPCs", :yellow, expected_zone.name)
|
116
|
+
else
|
117
|
+
unexpected_vpcs.each do |vpc|
|
118
|
+
actual_zone.disassociate_vpc(vpc)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
89
124
|
def walk_rrsets(expected_zone, actual_zone)
|
90
125
|
expected = collection_to_hash(expected_zone.rrsets, :name, :type, :set_identifier)
|
91
126
|
actual = collection_to_hash(actual_zone.rrsets, :name, :type, :set_identifier)
|
@@ -69,14 +69,27 @@ module Roadworker
|
|
69
69
|
def output_zone(zone)
|
70
70
|
name = zone[:name].inspect
|
71
71
|
rrsets = zone[:rrsets]
|
72
|
+
vpcs = output_vpcs(zone[:vpcs])
|
73
|
+
vpcs = " #{vpcs}\n\n" if vpcs
|
72
74
|
|
73
75
|
return(<<-EOS)
|
74
76
|
hosted_zone #{name} do
|
75
|
-
#{
|
77
|
+
#{vpcs
|
78
|
+
}#{rrsets.map {|i| output_rrset(i) }.join("\n").chomp}
|
76
79
|
end
|
77
80
|
EOS
|
78
81
|
end
|
79
82
|
|
83
|
+
def output_vpcs(vpcs)
|
84
|
+
return nil if (vpcs || []).empty?
|
85
|
+
|
86
|
+
vpcs.map {|vpc|
|
87
|
+
region = vpc[:vpc_region]
|
88
|
+
vpc_id = vpc[:vpc_id]
|
89
|
+
"vpc #{region.inspect}, #{vpc_id.inspect}"
|
90
|
+
}.join("\n ")
|
91
|
+
end
|
92
|
+
|
80
93
|
end # Converter
|
81
94
|
end # DSL
|
82
95
|
end # Roadworker
|
data/lib/roadworker/dsl.rb
CHANGED
@@ -38,9 +38,9 @@ module Roadworker
|
|
38
38
|
routefile = (file =~ %r|\A/|) ? file : File.expand_path(File.join(File.dirname(@path), file))
|
39
39
|
|
40
40
|
if File.exist?(routefile)
|
41
|
-
instance_eval(File.read(routefile))
|
41
|
+
instance_eval(File.read(routefile), routefile)
|
42
42
|
elsif File.exist?(routefile + '.rb')
|
43
|
-
instance_eval(File.read(routefile + '.rb'))
|
43
|
+
instance_eval(File.read(routefile + '.rb'), routefile + '.rb')
|
44
44
|
else
|
45
45
|
Kernel.require(file)
|
46
46
|
end
|
@@ -63,6 +63,7 @@ module Roadworker
|
|
63
63
|
|
64
64
|
@result = OpenStruct.new({
|
65
65
|
:name => name,
|
66
|
+
:vpcs => [],
|
66
67
|
:resource_record_sets => rrsets,
|
67
68
|
:rrsets => rrsets,
|
68
69
|
})
|
@@ -72,6 +73,24 @@ module Roadworker
|
|
72
73
|
|
73
74
|
private
|
74
75
|
|
76
|
+
def vpc(vpc_region, vpc_id)
|
77
|
+
unless vpc_region
|
78
|
+
raise "Invalid VPC Region: #{vpc_region.inspect}"
|
79
|
+
end
|
80
|
+
|
81
|
+
unless vpc_id
|
82
|
+
raise "Invalid VPC ID: #{vpc_id}"
|
83
|
+
end
|
84
|
+
|
85
|
+
vpc_h = {:vpc_region => vpc_region.to_s, :vpc_id => vpc_id.to_s}
|
86
|
+
|
87
|
+
if @result.vpcs.include?(vpc_h)
|
88
|
+
raise "VPC is already defined: #{vpc_h.inspect}"
|
89
|
+
end
|
90
|
+
|
91
|
+
@result.vpcs << vpc_h
|
92
|
+
end
|
93
|
+
|
75
94
|
def resource_record_set(rrset_name, type, &block)
|
76
95
|
if rrset_name.sub(/\.\Z/, '') !~ /#{Regexp.escape(@name.sub(/\.\Z/, ''))}\Z/i
|
77
96
|
raise "Invalid ResourceRecordSet Name: #{rrset_name}"
|
@@ -31,7 +31,12 @@ module Roadworker
|
|
31
31
|
|
32
32
|
def export_hosted_zones(hosted_zones)
|
33
33
|
Collection.batch(@options.route53.hosted_zones) do |zone|
|
34
|
-
zone_h = item_to_hash(zone, :name)
|
34
|
+
zone_h = item_to_hash(zone, :name, :vpcs)
|
35
|
+
|
36
|
+
if @options.target_zone
|
37
|
+
next unless zone_h[:name] =~ @options.target_zone
|
38
|
+
end
|
39
|
+
|
35
40
|
hosted_zones << zone_h
|
36
41
|
|
37
42
|
rrsets = []
|
@@ -1,6 +1,43 @@
|
|
1
|
-
require 'aws-sdk'
|
1
|
+
require 'aws-sdk-v1'
|
2
2
|
|
3
3
|
module AWS
|
4
|
+
module Core
|
5
|
+
class Client
|
6
|
+
|
7
|
+
# PTF:
|
8
|
+
class << self
|
9
|
+
alias load_api_config_orig load_api_config
|
10
|
+
|
11
|
+
def load_api_config(api_version)
|
12
|
+
yaml = load_api_config_orig(api_version)
|
13
|
+
|
14
|
+
if service_name == 'Route53'
|
15
|
+
rewrite_api(yaml)
|
16
|
+
end
|
17
|
+
|
18
|
+
return yaml
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def rewrite_api(yaml)
|
24
|
+
# XXX: Fix aws-sdk 1.5.8 bug
|
25
|
+
get_hosted_zone = yaml[:operations].find {|h| h[:name] == 'GetHostedZone' }
|
26
|
+
vpcs = get_hosted_zone[:outputs][:children]['VPCs']
|
27
|
+
|
28
|
+
if vpcs
|
29
|
+
vpc = vpcs[:children]['VPC']
|
30
|
+
|
31
|
+
if vpc[:rename] == :vp_cs
|
32
|
+
vpc[:rename] = :vpcs
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end # of class method
|
37
|
+
|
38
|
+
end # Client
|
39
|
+
end # Core
|
40
|
+
|
4
41
|
class Route53
|
5
42
|
|
6
43
|
# http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
|
@@ -9,6 +46,7 @@ module AWS
|
|
9
46
|
's3-website-us-west-2.amazonaws.com' => 'Z3BJ6K6RIION7M',
|
10
47
|
's3-website-us-west-1.amazonaws.com' => 'Z2F56UZL2M1ACD',
|
11
48
|
's3-website-eu-west-1.amazonaws.com' => 'Z1BKCTXD74EZPE',
|
49
|
+
's3-website.eu-central-1.amazonaws.com' => 'Z21DNDUVLTQW6Q',
|
12
50
|
's3-website-ap-southeast-1.amazonaws.com' => 'Z3O0J2DXBE1FTB',
|
13
51
|
's3-website-ap-southeast-2.amazonaws.com' => 'Z1WCIGYICN2BYD',
|
14
52
|
's3-website-ap-northeast-1.amazonaws.com' => 'Z2M4EHUR26P7ZW',
|
@@ -44,33 +44,46 @@ module Roadworker
|
|
44
44
|
|
45
45
|
def each
|
46
46
|
Collection.batch(@hosted_zones) do |zone|
|
47
|
-
yield(HostedZoneWrapper.new(zone, @options))
|
47
|
+
yield(HostedZoneWrapper.new(zone, zone.vpcs, @options))
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
def create(name, opts = {})
|
52
|
-
|
52
|
+
if vpc = opts[:vpc]
|
53
|
+
vpcs = [vpc]
|
54
|
+
else
|
55
|
+
vpcs = []
|
56
|
+
opts.delete(:vpc)
|
57
|
+
end
|
58
|
+
|
59
|
+
logmsg = 'Create HostedZone'
|
60
|
+
logmsg << " #{vpc.inspect}"
|
61
|
+
log(:info, logmsg, :cyan, name)
|
53
62
|
|
54
63
|
if @options.dry_run
|
55
|
-
|
64
|
+
opts.delete(:vpc)
|
65
|
+
zone = OpenStruct.new({:name => name, :rrsets => [], :vpcs => vpcs}.merge(opts))
|
56
66
|
else
|
57
67
|
zone = @hosted_zones.create(name, opts)
|
58
68
|
@options.hosted_zone_name = name
|
59
69
|
@options.updated = true
|
60
70
|
end
|
61
71
|
|
62
|
-
HostedZoneWrapper.new(zone, @options)
|
72
|
+
HostedZoneWrapper.new(zone, vpcs, @options)
|
63
73
|
end
|
64
74
|
end # HostedZoneCollection
|
65
75
|
|
66
76
|
class HostedZoneWrapper
|
67
77
|
include Roadworker::Log
|
68
78
|
|
69
|
-
def initialize(hosted_zone, options)
|
79
|
+
def initialize(hosted_zone, vpcs, options)
|
70
80
|
@hosted_zone = hosted_zone
|
81
|
+
@vpcs = vpcs
|
71
82
|
@options = options
|
72
83
|
end
|
73
84
|
|
85
|
+
attr_reader :vpcs
|
86
|
+
|
74
87
|
def resource_record_sets
|
75
88
|
ResourceRecordSetCollectionWrapper.new(@hosted_zone.rrsets, @hosted_zone, @options)
|
76
89
|
end
|
@@ -93,6 +106,33 @@ module Roadworker
|
|
93
106
|
end
|
94
107
|
end
|
95
108
|
|
109
|
+
def delete
|
110
|
+
if @options.force
|
111
|
+
log(:info, 'Delete HostedZone', :red, @hosted_zone.name)
|
112
|
+
|
113
|
+
self.rrsets.each do |record|
|
114
|
+
record.delete
|
115
|
+
end
|
116
|
+
|
117
|
+
unless @options.dry_run
|
118
|
+
@hosted_zone.delete
|
119
|
+
@options.updated = true
|
120
|
+
end
|
121
|
+
else
|
122
|
+
log(:info, 'Undefined HostedZone (pass `--force` if you want to remove)', :yellow, @hosted_zone.name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def associate_vpc(vpc)
|
127
|
+
log(:info, "Associate #{vpc.inspect}", :green, @hosted_zone.name)
|
128
|
+
@hosted_zone.associate_vpc(vpc) unless @options.dry_run
|
129
|
+
end
|
130
|
+
|
131
|
+
def disassociate_vpc(vpc)
|
132
|
+
log(:info, "Disassociate #{vpc.inspect}", :red, @hosted_zone.name)
|
133
|
+
@hosted_zone.disassociate_vpc(vpc) unless @options.dry_run
|
134
|
+
end
|
135
|
+
|
96
136
|
private
|
97
137
|
|
98
138
|
def method_missing(method_name, *args)
|
data/lib/roadworker/version.rb
CHANGED
metadata
CHANGED
@@ -1,35 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roadworker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- winebarrel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: aws-sdk
|
14
|
+
name: aws-sdk-v1
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
20
|
-
- - <
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 2.0.0
|
19
|
+
version: 1.58.0
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.
|
30
|
-
- - <
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 2.0.0
|
26
|
+
version: 1.58.0
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: term-ansicolor
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,16 +140,16 @@ dependencies:
|
|
146
140
|
name: rubydns
|
147
141
|
requirement: !ruby/object:Gem::Requirement
|
148
142
|
requirements:
|
149
|
-
- -
|
143
|
+
- - ~>
|
150
144
|
- !ruby/object:Gem::Version
|
151
|
-
version:
|
145
|
+
version: 0.8.5
|
152
146
|
type: :development
|
153
147
|
prerelease: false
|
154
148
|
version_requirements: !ruby/object:Gem::Requirement
|
155
149
|
requirements:
|
156
|
-
- -
|
150
|
+
- - ~>
|
157
151
|
- !ruby/object:Gem::Version
|
158
|
-
version:
|
152
|
+
version: 0.8.5
|
159
153
|
- !ruby/object:Gem::Dependency
|
160
154
|
name: coveralls
|
161
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -180,7 +174,6 @@ extra_rdoc_files: []
|
|
180
174
|
files:
|
181
175
|
- README.md
|
182
176
|
- bin/roadwork
|
183
|
-
- lib/roadworker.rb
|
184
177
|
- lib/roadworker/client.rb
|
185
178
|
- lib/roadworker/collection.rb
|
186
179
|
- lib/roadworker/dsl-converter.rb
|
@@ -193,6 +186,7 @@ files:
|
|
193
186
|
- lib/roadworker/route53-wrapper.rb
|
194
187
|
- lib/roadworker/string-ext.rb
|
195
188
|
- lib/roadworker/version.rb
|
189
|
+
- lib/roadworker.rb
|
196
190
|
homepage: https://github.com/winebarrel/roadworker
|
197
191
|
licenses:
|
198
192
|
- MIT
|
@@ -213,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
213
207
|
version: '0'
|
214
208
|
requirements: []
|
215
209
|
rubyforge_project:
|
216
|
-
rubygems_version: 2.
|
210
|
+
rubygems_version: 2.0.14
|
217
211
|
signing_key:
|
218
212
|
specification_version: 4
|
219
213
|
summary: Roadworker is a tool to manage Route53.
|