r53z 0.3.2 → 0.3.3

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: 4a76e281d58be3c97125591da8dd480f32cc6cb5
4
- data.tar.gz: 68e49615f4b31b8f390e2c92c0b4eeb7d36251e4
3
+ metadata.gz: 83c9097772ffb2446770deb433f151234c7d48c6
4
+ data.tar.gz: f4c97405669e49664f15461cea6df4edb0dbc8da
5
5
  SHA512:
6
- metadata.gz: 0f3e3e61987f2387d890147b5d71945b6cbb8a815ec35640f6d7c773943651d075eadd0ef19f1b7569f4dbb0f883cf30451325332e170802e98a0ef6233277a5
7
- data.tar.gz: 90e2b3812b188c15a6f556eda3d3047eecf70fd4eeafbff9df995f2f8c671ddc71933a809433e9caa6d11afccc8b0a6e840371365d23562279f213e2d9fe561d
6
+ metadata.gz: 72b8bee3563a3eb8804473695ff5c9fe0d58115d544aef2b4fab69a098c26709b3f272fe0fdd0550ebad446ff4b2404f0f3d25ddb673c7d98f5ae492e729563c
7
+ data.tar.gz: b942db9c3fc19c72b056b75cf388271e3c85222a62426e04bff7b64a9a606b3e2017a3d5efcbfd76a0c2e74c7fc04dee84ade1807e6e8fa6cf02a979acdccfbd
data/.gitignore CHANGED
@@ -45,9 +45,9 @@ build-iPhoneSimulator/
45
45
 
46
46
  # for a library or gem, you might want to ignore these files since the code is
47
47
  # intended to run in multiple environments; otherwise, check them in:
48
- # Gemfile.lock
49
- # .ruby-version
50
- # .ruby-gemset
48
+ Gemfile.lock
49
+ .ruby-version
50
+ .ruby-gemset
51
51
 
52
52
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
53
53
  .rvmrc
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- r53z (0.3.1)
4
+ r53z (0.3.3)
5
5
  aws-sdk
6
6
  inifile
7
7
  methadone (~> 1.9.2)
data/README.md CHANGED
@@ -4,6 +4,8 @@ A simple CLI, REPL, and library for managing Route 53. It's primary purpose is t
4
4
 
5
5
  ## Installation
6
6
 
7
+ r53z currently requires version 2.1.0 of Ruby, or greater (due to use of named method arguments without default values).
8
+
7
9
  Add this line to your application's Gemfile:
8
10
 
9
11
  ```ruby
@@ -14,12 +16,14 @@ And then execute:
14
16
 
15
17
  $ bundle
16
18
 
17
- Or install it yourself as:
19
+ Or install it yourself as (it's on rubygems.org, but installation of the binary isn't working right yet, will be fixed sooon):
18
20
 
19
21
  $ gem install r53z
20
22
 
21
23
  ## Usage
22
24
 
25
+ **NOTE:** Don't get too attached to the current CLI options. I'm rewriting the option parser to use sub-commands in the near future. So, if you love it like it is (surely, nobody could love it like it is), you'll need to lock in a version that still has this parser.
26
+
23
27
  Configure a credentials file in `~/.aws/credentials` (this should be an INI file; same as several other AWS utilities expect). It'll look something like this:
24
28
 
25
29
  ```ini
@@ -36,7 +40,7 @@ Usage: r53z [options] [args...]
36
40
 
37
41
  Simple CLI to manage, backup, and restore, Route 53 zones
38
42
 
39
- v0.2.0
43
+ v0.3.0
40
44
 
41
45
  Options:
42
46
  -h, --help Show command line help
@@ -118,6 +122,39 @@ $ r53z --delete swelljoe.com virtualmin.com
118
122
 
119
123
  Specify the credentials configuration file on the command line. The file must be an INI file. By default, it will look for a file in ~/.aws/credentials (which is common across several AWS management tools). You can use the `--section` option to choose what section of the file to use.
120
124
 
125
+ ## More Examples
126
+
127
+ ### Working With Delegation Sets
128
+
129
+ Finding the delegation set of a zone, and backing up all zones that share that delegation set:
130
+
131
+ ```
132
+ $ r53z --list-delegation-sets swelljoe.com
133
+ {
134
+ "id": "/delegationset/NKXKQ56JI1ZGT",
135
+ "caller_reference": "r53z-create-del-set-hh0xf3dm0xp7nuvt",
136
+ "name_servers": [
137
+ "ns-885.awsdns-46.net",
138
+ "ns-2016.awsdns-60.co.uk",
139
+ "ns-417.awsdns-52.com",
140
+ "ns-1299.awsdns-34.org"
141
+ ]
142
+ }
143
+ $ r53z --export ~/dumps --delegation-set "/delegationset/NKXKQ56JI1ZGT"
144
+ ```
145
+
146
+ Creating a new zone with an existing delegation set:
147
+
148
+ ```
149
+ $ r53z --create swelljoe.com --comment "dootdoot" --delegation-set "/delegationset/NKXKQ56JI1ZGT"
150
+ ```
151
+
152
+ Restoring a zone into a specific delegation set (this will override the delegation set specified in the dump file):
153
+
154
+ ```
155
+ $ r53z --restore ~/dumps swelljoe.com --delegation-set "/delegationset/NKXKQ56JI1ZGT"
156
+ ```
157
+
121
158
  ## Development
122
159
 
123
160
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/bin/r53z CHANGED
@@ -28,7 +28,8 @@ class App
28
28
  on("-u SECTION", "--section", "Section (user) in the credentials file to use.")
29
29
  on("-g ID", "--delegation-set", "Delegation set ID to use for various operations.")
30
30
  on("-t", "--list-delegation-sets", "List delegation set for named zone, or all sets if no zone specified.")
31
- on("-D", "--delete-delegation-sets", "Delete one or more delegation sets by ID (WARNING: No confirmation!")
31
+ on("-S", "--create-delegation-sets", "Create one or more delegation sets, optionally associated with listed zones.")
32
+ on("-D", "--delete-delegation-sets", "Delete one or more delegation sets by ID (WARNING: No confirmation!)")
32
33
  on("-N ID", "--name-servers", "List name servers for delegation set.")
33
34
  # args greedily grabs any files or zones listed after the options
34
35
  arg(:args, :any)
data/lib/r53z/cli.rb CHANGED
@@ -14,15 +14,18 @@ module R53z
14
14
  # XXX Dispatch table seems smarter...can't figure out how to call methods based
15
15
  # directly on hash keys at the moment.
16
16
  if options[:export]
17
+ unless options[:export].is_a? String
18
+ exit_now! "Export must have a valid directory path for dump files."
19
+ end
17
20
  unless Dir.exists?(File.expand_path(options[:export]))
18
- help_now! "Export requires a directory path for zone files."
21
+ exit_now! "Directory " + options[:export] + " does not exist."
19
22
  end
20
23
  export(:options => options, :args => args)
21
24
  end
22
25
 
23
26
  if options[:restore]
24
27
  unless Dir.exists?(File.expand_path(options[:restore]))
25
- help_now! "Restore requires a directory containing zone files and optionally one or more zones to restore."
28
+ exit_now! "Restore requires a directory containing zone files and optionally one or more zones to restore."
26
29
  end
27
30
  restore(:options => options, :args => args)
28
31
  end
@@ -37,7 +40,7 @@ module R53z
37
40
 
38
41
  if options[:delete]
39
42
  if args.empty?
40
- help_now! "Delete requires one or more zone names."
43
+ exit_now! "Delete requires one or more zone names."
41
44
  end
42
45
  args.each do |name|
43
46
  if @client.list(name: name).any?
@@ -52,9 +55,13 @@ module R53z
52
55
  delegation_sets(args)
53
56
  end
54
57
 
58
+ if options['create-delegation-sets']
59
+ create_delegation(args)
60
+ end
61
+
55
62
  if options['delete-delegation-sets']
56
63
  if args.empty?
57
- help_now! "Delete delegation sets requires one or more delegation set IDs."
64
+ exit_now! "Deleting delegation sets requires one or more delegation set IDs."
58
65
  end
59
66
  args.each do |id|
60
67
  @client.delete_delegation_set(id: id)
@@ -63,7 +70,7 @@ module R53z
63
70
 
64
71
  if options['record-sets']
65
72
  if args.empty?
66
- help_now! "List record sets requires one or more zone names."
73
+ exit_now! "List record sets requires one or more zone names."
67
74
  end
68
75
  record_sets(args)
69
76
  end
@@ -109,8 +116,10 @@ module R53z
109
116
  end
110
117
  end
111
118
 
119
+ delegation = options['delegation-set'] or nil
120
+
112
121
  zones.each do |zone|
113
- @client.restore(path, zone)
122
+ @client.restore(path, zone, delegation)
114
123
  end
115
124
  end
116
125
 
@@ -143,6 +152,10 @@ module R53z
143
152
  @client.create(info: zone_data)
144
153
  end
145
154
 
155
+ def add_record(options, args)
156
+ # Populate record set hash
157
+ end
158
+
146
159
  def delegation_sets(args)
147
160
  # show them all
148
161
  if args.empty?
@@ -163,6 +176,30 @@ module R53z
163
176
  end
164
177
  end
165
178
 
179
+ def create_delegation(args)
180
+ # further validation
181
+ zones = []
182
+ # No zones specified, create a new unassociated delegation set
183
+ if args.empty?
184
+ @client.create_delegation_set
185
+ end
186
+
187
+ args.each do |name|
188
+ # Make sure at least one specified zone exists
189
+ if @client.list(name: name)
190
+ zones.push(name)
191
+ else
192
+ puts "Couldn't locate zone " + name unless @client.list(name)
193
+ end
194
+ if zones.empty?
195
+ exit_now! "Couldn't find any of the specified zones."
196
+ end
197
+ zones.each do |zone|
198
+ @client.create_delegation_set(@client.get_zone_id(zone))
199
+ end
200
+ end
201
+ end
202
+
166
203
  def record_sets(args)
167
204
  args.each do |name|
168
205
  zone_id = @client.get_zone_id(name)
data/lib/r53z/client.rb CHANGED
@@ -13,30 +13,47 @@ module R53z
13
13
  end
14
14
 
15
15
  # list one or all zones by name and ID
16
+ # XXX Should ideally be a lazy iterator, need to read up on how that's
17
+ # done in Ruby.
16
18
  def list(name: nil, delegation_set_id: nil)
17
- begin
18
- zones = self.client.list_hosted_zones(
19
- delegation_set_id: delegation_set_id
20
- )['hosted_zones']
21
- rescue Aws::Route53::Errors::ServiceError
22
- error "Failed to list zones" # XXX How do we get AWS error message out of it?
23
- end
24
-
25
19
  rv = []
26
- if zones
27
- zones.each do |zone|
28
- if name
29
- unless name[-1] == '.'
30
- name = name + '.'
31
- end
32
- unless name == zone[:name]
33
- next
34
- end
20
+ if name
21
+ name = name.to_s + "." unless name[-1] == '.'
22
+ zone = self.client.list_hosted_zones_by_name({
23
+ dns_name: name,
24
+ max_items: 1
25
+ })
26
+ # Response will always contain some zone, even if the one
27
+ # we want doesn't exist...so, if no match, return empty set
28
+ if zone.hosted_zones.first and zone.hosted_zones.first.name == name
29
+ rv.push({
30
+ :name => zone.hosted_zones.first.name,
31
+ :id => zone.hosted_zones.first.id,
32
+ })
33
+ end
34
+ else
35
+ is_truncated = true
36
+ marker = nil
37
+ # If more than 100, will be divided into sets, so we have to
38
+ # poll multiple times
39
+ while is_truncated
40
+ if marker
41
+ resp = self.client.list_hosted_zones(
42
+ delegation_set_id: delegation_set_id,
43
+ marker: marker,
44
+ )
45
+ else
46
+ resp = self.client.list_hosted_zones(
47
+ delegation_set_id: delegation_set_id)
48
+ end
49
+ is_truncated = resp['is_truncated']
50
+ marker = resp['next_marker']
51
+ resp['hosted_zones'].each do |z|
52
+ rv.push({:name => z[:name], :id => z[:id]})
35
53
  end
36
- rv.push({:name => zone[:name], :id => zone[:id]})
37
54
  end
38
55
  end
39
- rv
56
+ return rv
40
57
  end
41
58
 
42
59
  # Create zone with record(s) from an info and records hash
@@ -145,7 +162,7 @@ module R53z
145
162
 
146
163
  # Restore a zone from the given path. It expects files named
147
164
  # zone.zoneinfo.json and zone.json
148
- def restore(path, domain)
165
+ def restore(path, domain, delegation = nil)
149
166
  # normalize domain
150
167
  unless domain[-1] == '.'
151
168
  domain = domain + '.'
@@ -153,6 +170,10 @@ module R53z
153
170
  # Load up the zone info file
154
171
  file = File.join(path, domain)
155
172
  info = R53z::JsonFile.read_json(path: file + "zoneinfo")
173
+ if delegation
174
+ # inject the specified delegation set into info, overriding file
175
+ info[:delegation_set] = {:id => delegation }
176
+ end
156
177
  records = R53z::JsonFile.read_json(path: file)
157
178
  # create the zone and the record sets
158
179
  self.create(:info => info, :records => records)
data/lib/r53z/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module R53z
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
data/r53z.gemspec CHANGED
@@ -14,8 +14,8 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "http://github.com/swelljoe/r53z"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
- spec.bindir = "exe"
18
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
17
+ spec.bindir = "bin"
18
+ spec.executables = "r53z"
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.required_ruby_version = '>= 2.1.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: r53z
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Cooper
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-29 00:00:00.000000000 Z
11
+ date: 2016-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -139,7 +139,8 @@ dependencies:
139
139
  description:
140
140
  email:
141
141
  - swelljoe@gmail.com
142
- executables: []
142
+ executables:
143
+ - r53z
143
144
  extensions: []
144
145
  extra_rdoc_files: []
145
146
  files: