roadworker 0.4.12 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 18cf85508a90ec02fdea7a76237f02b57f9f84f0
4
- data.tar.gz: 4b06aef141392019fd49424b5c4c21f5810d9003
3
+ metadata.gz: dc7cfa6e280e4ea6a6c8681638c62f850bd060cb
4
+ data.tar.gz: 1759745736aaa13e12da2bfd7f3ca2dba5ed8b3e
5
5
  SHA512:
6
- metadata.gz: fb46ab01d4138372ea93f08a5797aa2f8e4ff60d9e5c9e9d8ada4fa7c917a70e89e987ee2a244c87b47e1cbef00c2cb450777c90d567386e1516a39e0763def7
7
- data.tar.gz: 0f9ca876a42b2961401646d6abfd42da0de5c9b6d2dc4672306e1b27274468383a66cc0e60d42817a7d3cab418355389d14f9cc078911bfa4ed26dcce0871994
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
@@ -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('' , '--no-color') { options[:color] = false }
52
- opt.on('' , '--debug') { options[:debug] = true }
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 = {}
@@ -77,15 +77,50 @@ module Roadworker
77
77
 
78
78
  expected.each do |keys, expected_zone|
79
79
  name = keys[0]
80
- actual_zone = actual.delete(keys) || @route53.hosted_zones.create(name)
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
- #{rrsets.map {|i| output_rrset(i) }.join("\n").chomp}
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
@@ -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
- log(:info, 'Create HostedZone', :cyan, name)
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
- zone = OpenStruct.new({:name => name, :rrsets => []}.merge(opts))
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)
@@ -1,5 +1,3 @@
1
1
  module Roadworker
2
- VERSION = "0.4.12"
2
+ VERSION = "0.5.0"
3
3
  end
4
-
5
- Version = Roadworker::VERSION
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.12
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-10-11 00:00:00.000000000 Z
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.55.0
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.55.0
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: '0'
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: '0'
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.4.1
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.