Class: R53z::Client
- Inherits:
-
Object
- Object
- R53z::Client
- Includes:
- Methadone::CLILogging, Methadone::Main
- Defined in:
- lib/r53z/client.rb
Instance Attribute Summary collapse
-
#client ⇒ Object
Returns the value of attribute client.
Instance Method Summary collapse
-
#create(info:, records: nil) ⇒ Object
Create zone with record(s) from an info and records hash.
-
#create_delegation_set(zone_id = nil) ⇒ Object
create a new delegation set, optionally associated with an existing zone.
-
#delete(name, id: nil) ⇒ Object
delete a zone by name, optionally by ID.
-
#delete_all_rr_sets(zone_id) ⇒ Object
delete all of the resource record sets in a zone (this is required to delete a zone.
-
#delete_delegation_set(id: nil, name: nil) ⇒ Object
delete a delegation set by ID or name.
-
#dump(dirpath, name) ⇒ Object
dump a zone to a direcory.
-
#get_delegation_set(id) ⇒ Object
get details of a delegation set specified by ID, incuding name servers.
-
#get_delegation_set_id(name) ⇒ Object
Get delegation set ID for the given zone.
-
#get_zone_id(name) ⇒ Object
Get the zone id from name.
-
#initialize(section, creds) ⇒ Client
constructor
A new instance of Client.
-
#list(name: nil, delegation_set_id: nil) ⇒ Object
list one or all zones by name and ID XXX Should ideally be a lazy iterator, need to read up on how that’s done in Ruby.
-
#list_by_id(id) ⇒ Object
Get zone information in a different way for testing.
-
#list_delegation_sets ⇒ Object
list all delegation sets.
- #list_records(zone_id) ⇒ Object
-
#random_string(len = 16) ⇒ Object
random string generator helper function.
-
#restore(path, domain, delegation = nil) ⇒ Object
Restore a zone from the given path.
Constructor Details
#initialize(section, creds) ⇒ Client
Returns a new instance of Client.
7 8 9 10 11 12 13 |
# File 'lib/r53z/client.rb', line 7 def initialize(section, creds) @client = Aws::Route53::Client.new( access_key_id: creds[section]['aws_access_key_id'], secret_access_key: creds[section]['aws_secret_access_key'], region: creds[section]['region'] ) end |
Instance Attribute Details
#client ⇒ Object
Returns the value of attribute client.
5 6 7 |
# File 'lib/r53z/client.rb', line 5 def client @client end |
Instance Method Details
#create(info:, records: nil) ⇒ Object
Create zone with record(s) from an info and records hash
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 |
# File 'lib/r53z/client.rb', line 63 def create(info:, records: nil) rv = {} # pile up the responses in a single hash #if self.list(name: info[:name]).any? # error(info[:name].to_s + " already exists") #end # XXX: AWS sends out a data structure with config:, but expects # hosted_zone_config: on create/restore. argh. # XXX: also, private_zone is not accepted here for some reason zone = info[:hosted_zone] # Populate a zone_data hash with options for zone creation zone_data = {} zone_data[:name] = zone[:name] zone_data[:caller_reference] = 'r53z-create-' + self.random_string if zone[:config] and zone[:config][:comment] zone_data[:hosted_zone_config] = {} zone_data[:hosted_zone_config][:comment] = zone[:config][:comment] end if info[:delegation_set] and info[:delegation_set][:id] zone_data[:delegation_set_id] = info[:delegation_set][:id] end zone_resp = self.client.create_hosted_zone(zone_data) rv[:hosted_zone_resp] = zone_resp rv[:record_set_resp] = [] # Optionally populate records if records records.each do |record| # skip these, as they are handled separately (delegation sets) unless (record[:type] == "NS" || record[:type] == "SOA") record_resp = self.client.change_resource_record_sets({ :hosted_zone_id => zone_resp[:hosted_zone][:id], :change_batch => { :changes => [ { :action => "CREATE", :resource_record_set => record } ] } }) rv[:record_set_resp].push(record_resp) end end end return rv end |
#create_delegation_set(zone_id = nil) ⇒ Object
create a new delegation set, optionally associated with an existing zone
199 200 201 202 203 204 |
# File 'lib/r53z/client.rb', line 199 def create_delegation_set(zone_id = nil) self.client.create_reusable_delegation_set({ caller_reference: 'r53z-create-del-set-' + self.random_string, hosted_zone_id: zone_id }) end |
#delete(name, id: nil) ⇒ Object
delete a zone by name, optionally by ID
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/r53z/client.rb', line 111 def delete(name, id: nil) # if we got both, demand nil for name, because AWS allows multiples if name and id raise "Name should be nil when id is provided." end unless id id = self.list(:name => name).first[:id] end # Can't delete unless empty of record sets self.delete_all_rr_sets(id) client.delete_hosted_zone(:id => id) end |
#delete_all_rr_sets(zone_id) ⇒ Object
delete all of the resource record sets in a zone (this is required to delete a zone
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/r53z/client.rb', line 126 def delete_all_rr_sets(zone_id) self.list_records(zone_id).reject do |rs| (rs[:type] == "NS" || rs[:type] == "SOA") end.each do |record_set| self.client.change_resource_record_sets({ :hosted_zone_id => zone_id, :change_batch => { :changes => [{ :action=> "DELETE", :resource_record_set => record_set }] } }) end end |
#delete_delegation_set(id: nil, name: nil) ⇒ Object
delete a delegation set by ID or name
220 221 222 223 224 225 226 227 |
# File 'lib/r53z/client.rb', line 220 def delete_delegation_set(id: nil, name: nil) if name and not id id = get_delegation_set_id(name) end self.client.delete_reusable_delegation_set({ id: id }) end |
#dump(dirpath, name) ⇒ Object
dump a zone to a direcory. Will generate two files; a zoneinfo file and a records file.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/r53z/client.rb', line 144 def dump(dirpath, name) # Get the ID zone_id = self.list(:name => name).first[:id] # normalize name unless name[-1] == '.' name = name + '.' end # dump the record sets R53z::JsonFile.write_json( path: File.join(dirpath, name), data: self.list_records(zone_id)) # Dump the zone metadata, plus the delegated set info out = { :hosted_zone => self.client.get_hosted_zone({ :id => zone_id}).hosted_zone.to_h, :delegation_set => self.client.get_hosted_zone({:id => zone_id}).delegation_set.to_h } R53z::JsonFile.write_json( path: File.join(dirpath, name + "zoneinfo"), data: out) end |
#get_delegation_set(id) ⇒ Object
get details of a delegation set specified by ID, incuding name servers
213 214 215 216 217 |
# File 'lib/r53z/client.rb', line 213 def get_delegation_set(id) self.client.get_reusable_delegation_set({ id: id }) end |
#get_delegation_set_id(name) ⇒ Object
Get delegation set ID for the given zone
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/r53z/client.rb', line 230 def get_delegation_set_id(name) begin zone_id = self.list(:name => name).first[:id] rescue return nil end return self.client.get_hosted_zone({ id: zone_id }).delegation_set[:id] end |
#get_zone_id(name) ⇒ Object
Get the zone id from name
251 252 253 |
# File 'lib/r53z/client.rb', line 251 def get_zone_id(name) self.list(:name => name).first[:id] end |
#list(name: nil, delegation_set_id: nil) ⇒ Object
list one or all zones by name and ID XXX Should ideally be a lazy iterator, need to read up on how that’s done in Ruby.
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 |
# File 'lib/r53z/client.rb', line 18 def list(name: nil, delegation_set_id: nil) rv = [] if name name = name.to_s + "." unless name[-1] == '.' zone = self.client.list_hosted_zones_by_name({ dns_name: name, max_items: 1 }) # Response will always contain some zone, even if the one # we want doesn't exist...so, if no match, return empty set if zone.hosted_zones.first and zone.hosted_zones.first.name == name rv.push({ :name => zone.hosted_zones.first.name, :id => zone.hosted_zones.first.id, }) end else is_truncated = true marker = nil # If more than 100, will be divided into sets, so we have to # poll multiple times while is_truncated if marker resp = self.client.list_hosted_zones( delegation_set_id: delegation_set_id, marker: marker, ) # R53 imposes a 5 request per second limit # Could catch "throttling"/"rate exceeded" error and retry sleep 0.3 else resp = self.client.list_hosted_zones( delegation_set_id: delegation_set_id) end is_truncated = resp['is_truncated'] marker = resp['next_marker'] resp['hosted_zones'].each do |z| rv.push({:name => z[:name], :id => z[:id]}) end end end return rv end |
#list_by_id(id) ⇒ Object
Get zone information in a different way for testing
242 243 244 245 246 247 248 |
# File 'lib/r53z/client.rb', line 242 def list_by_id(id) # no begin, let exceptions bubble up, maybe it'll give useful data zone = self.client.get_hosted_zone({ id: id }).hosted_zone return zone end |
#list_delegation_sets ⇒ Object
list all delegation sets
207 208 209 210 |
# File 'lib/r53z/client.rb', line 207 def list_delegation_sets resp = self.client.list_reusable_delegation_sets({}) return resp.delegation_sets end |
#list_records(zone_id) ⇒ Object
189 190 191 192 193 194 195 196 |
# File 'lib/r53z/client.rb', line 189 def list_records(zone_id) records = self.client.list_resource_record_sets(hosted_zone_id: zone_id) rv = [] records[:resource_record_sets].each do |record| rv.push(record.to_h) end rv end |
#random_string(len = 16) ⇒ Object
random string generator helper function
256 257 258 |
# File 'lib/r53z/client.rb', line 256 def random_string(len=16) rand(36**len).to_s(36) end |
#restore(path, domain, delegation = nil) ⇒ Object
Restore a zone from the given path. It expects files named zone.zoneinfo.json and zone.json
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/r53z/client.rb', line 172 def restore(path, domain, delegation = nil) # normalize domain unless domain[-1] == '.' domain = domain + '.' end # Load up the zone info file file = File.join(path, domain) info = R53z::JsonFile.read_json(path: file + "zoneinfo") if delegation # inject the specified delegation set into info, overriding file info[:delegation_set] = {:id => delegation } end records = R53z::JsonFile.read_json(path: file) # create the zone and the record sets self.create(:info => info, :records => records) end |