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 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.