class Google::Cloud::Dns::Zone

# DNS Zone

The managed zone is the container for DNS records for the same DNS name suffix and has a set of name servers that accept and responds to queries. A project can have multiple managed zones, but they must each have a unique name.

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
zone.records.each do |record|
  puts record.name
end

@see cloud.google.com/dns/zones/ Managing Zones

Attributes

gapi[RW]

@private The Google API Client object.

service[RW]

@private The Service object.

Public Class Methods

from_gapi(gapi, conn) click to toggle source

@private New Zone from a Google API Client object.

# File lib/google/cloud/dns/zone.rb, line 687
def self.from_gapi gapi, conn
  new.tap do |f|
    f.gapi = gapi
    f.service = conn
  end
end
new() click to toggle source

@private Create an empty Zone object.

# File lib/google/cloud/dns/zone.rb, line 56
def initialize
  @service = nil
  @gapi = {}
end

Public Instance Methods

add(name, type, ttl, data, skip_soa: nil, soa_serial: nil) click to toggle source

Adds a record to the Zone. In order to update existing records, or add and delete records in the same transaction, use update.

This operation automatically updates the SOA record serial number unless prevented with the `skip_soa` option. See {#update} for details.

@param [String] name The owner of the record. For example:

`example.com.`.

@param [String] type The identifier of a [supported record

type](https://cloud.google.com/dns/what-is-cloud-dns).
For example: `A`, `AAAA`, `CNAME`, `MX`, or `TXT`.

@param [Integer] ttl The number of seconds that the record can be

cached by resolvers.

@param [String, Array<String>] data The resource record data, as

determined by `type` and defined in [RFC
1035 (section 5)](http://tools.ietf.org/html/rfc1035#section-5) and
[RFC 1034
(section 3.6.1)](http://tools.ietf.org/html/rfc1034#section-3.6.1).
For example: `192.0.2.1` or `example.com.`.

@param [Boolean] skip_soa Do not automatically update the SOA record

serial number. See {#update} for details.

@param [Integer+, lambda, Proc] soa_serial A value (or a lambda or

Proc returning a value) for the new SOA record serial number. See
{#update} for details.

@return [Google::Cloud::Dns::Change]

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
change = zone.add "example.com.", "A", 86400, ["1.2.3.4"]
# File lib/google/cloud/dns/zone.rb, line 535
def add name, type, ttl, data, skip_soa: nil, soa_serial: nil
  update [record(name, type, ttl, data)], [],
         skip_soa: skip_soa, soa_serial: soa_serial
end
change(change_id) click to toggle source

Retrieves an existing change by id.

@param [String] change_id The id of a change.

@return [Google::Cloud::Dns::Change, nil] Returns `nil` if the change

does not exist.

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
change = zone.change "2"
if change
  puts "#{change.id} - #{change.started_at} - #{change.status}"
end
# File lib/google/cloud/dns/zone.rb, line 185
def change change_id
  ensure_service!
  gapi = service.get_change id, change_id
  Change.from_gapi gapi, self
rescue Google::Cloud::NotFoundError
  nil
end
Also aliased as: find_change, get_change
changes(token: nil, max: nil, order: nil) click to toggle source

Retrieves the list of changes belonging to the zone.

@param [String] token A previously-returned page token representing

part of the larger set of results to view.

@param [Integer] max Maximum number of changes to return. @param [Symbol, String] order Sort the changes by change sequence.

Acceptable values are:

* `asc` - Sort by ascending change sequence
* `desc` - Sort by descending change sequence

@return [Array<Google::Cloud::Dns::Change>] (See

{Google::Cloud::Dns::Change::List})

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
changes = zone.changes
changes.each do |change|
  puts "#{change.id} - #{change.started_at} - #{change.status}"
end

@example The changes can be sorted by change sequence:

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
changes = zone.changes order: :desc

@example Retrieve all changes: (See {Change::List#all})

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
changes = zone.changes
changes.all do |change|
  puts "#{change.id} - #{change.status}"
end
# File lib/google/cloud/dns/zone.rb, line 238
def changes token: nil, max: nil, order: nil
  ensure_service!
  # Fix the sort options
  order = adjust_change_sort_order order
  sort  = "changeSequence" if order
  # Continue with the API call
  gapi = service.list_changes id, token: token, max: max,
                                  order: order, sort: sort
  Change::List.from_gapi gapi, self, max, order
end
Also aliased as: find_changes
clear!() click to toggle source

Removes non-essential records from the zone. Only NS and SOA records will be kept.

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
zone.clear!
# File lib/google/cloud/dns/zone.rb, line 161
def clear!
  non_essential = records.all.reject { |r| ["SOA", "NS"].include? r.type }
  change = update [], non_essential
  change&.wait_until_done!
end
created_at() click to toggle source

The time that this resource was created on the server.

# File lib/google/cloud/dns/zone.rb, line 113
def created_at
  Time.parse @gapi.creation_time
rescue StandardError
  nil
end
delete(force: false) click to toggle source

Permanently deletes the zone.

@param [Boolean] force If `true`, ensures the deletion of the zone by

first deleting all records. If `false` and the zone contains
non-essential records, the request will fail. Default is `false`.

@return [Boolean] Returns `true` if the zone was deleted.

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
zone.delete

@example The zone can be forcefully deleted with the `force` option:

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
zone.delete force: true
# File lib/google/cloud/dns/zone.rb, line 142
def delete force: false
  clear! if force

  ensure_service!
  service.delete_zone id
  true
end
description() click to toggle source

A string of at most 1024 characters associated with this resource for the user's convenience. Has no effect on the managed zone's function.

# File lib/google/cloud/dns/zone.rb, line 89
def description
  @gapi.description
end
dns() click to toggle source

The DNS name of this managed zone, for instance “example.com.”.

# File lib/google/cloud/dns/zone.rb, line 81
def dns
  @gapi.dns_name
end
export(path) click to toggle source

Exports the zone to a local [DNS zone file](en.wikipedia.org/wiki/Zone_file).

@param [String] path The path on the local file system to write the

data to. The path provided must be writable.

@return [File] An object on the local file system.

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"

zone.export "path/to/db.example.com"
# File lib/google/cloud/dns/zone.rb, line 343
def export path
  File.open path, "w" do |f|
    f.write to_zonefile
  end
end
find_change(change_id)
Alias for: change
find_changes(token: nil, max: nil, order: nil)
Alias for: changes
find_records(name = nil, type = nil, token: nil, max: nil)
Alias for: records
fqdn(domain_name) click to toggle source

This helper converts the given domain name or subdomain (e.g., `www`) fragment to a [fully qualified domain name (FQDN)](en.wikipedia.org/wiki/Fully_qualified_domain_name) for the zone's dns. If the argument is already a FQDN, it is returned unchanged.

@param [String] domain_name The name to convert to a fully qualified

domain name.

@return [String] A fully qualified domain name.

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
zone.fqdn "www" #=> "www.example.com."
zone.fqdn "@" #=> "example.com."
zone.fqdn "mail.example.com." #=> "mail.example.com."
# File lib/google/cloud/dns/zone.rb, line 681
def fqdn domain_name
  Service.fqdn domain_name, dns
end
get_change(change_id)
Alias for: change
id() click to toggle source

Unique identifier for the resource; defined by the server.

# File lib/google/cloud/dns/zone.rb, line 64
def id
  @gapi.id
end
import(path_or_io, only: nil, except: nil, skip_soa: nil, soa_serial: nil) click to toggle source

Imports resource records from a [DNS zone file](en.wikipedia.org/wiki/Zone_file), adding the new records to the zone, without removing any existing records from the zone.

Because the Google Cloud DNS API only accepts a single resource record for each `name` and `type` combination (with multiple `data` elements), the zone file's records are merged as necessary. During this merge, the lowest `ttl` of the merged records is used. If none of the merged records have a `ttl` value, the zone file's global TTL is used for the record.

The zone file's SOA and NS records are not imported, because the zone was given SOA and NS records when it was created. These generated records point to Cloud DNS name servers.

This operation automatically updates the SOA record serial number unless prevented with the `skip_soa` option. See {#update} for details.

The Google Cloud DNS service requires that record names and data use fully-qualified addresses. The @ symbol is not accepted, nor are unqualified subdomain addresses like `www`. If your zone file contains such values, you may need to pre-process it in order for the import operation to succeed.

@param [String, IO] path_or_io The path to a zone file on the

filesystem, or an IO instance from which zone file data can be read.

@param [String, Array<String>] only Include only records of this type

or types.

@param [String, Array<String>] except Exclude records of this type or

types.

@param [Boolean] skip_soa Do not automatically update the SOA record

serial number. See {#update} for details.

@param [Integer, lambda, Proc] soa_serial A value (or a lambda or Proc

returning a value) for the new SOA record serial number. See
{#update} for details.

@return [Google::Cloud::Dns::Change] A new change adding the imported

Record instances.

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
change = zone.import "path/to/db.example.com"
# File lib/google/cloud/dns/zone.rb, line 397
def import path_or_io, only: nil, except: nil,
           skip_soa: nil, soa_serial: nil
  except = (Array(except).map(&:to_s).map(&:upcase) + ["SOA", "NS"]).uniq
  importer = Google::Cloud::Dns::Importer.new self, path_or_io
  additions = importer.records only: only, except: except
  update additions, [], skip_soa: skip_soa, soa_serial: soa_serial
end
modify(name, type, skip_soa: nil, soa_serial: nil, &block) click to toggle source

Modifies records on the Zone. Records matching the `name` and `type` are yielded to the block where they can be modified.

This operation automatically updates the SOA record serial number unless prevented with the `skip_soa` option. See {#update} for details.

@param [String] name The owner of the record. For example:

`example.com.`.

@param [String] type The identifier of a [supported record

type](https://cloud.google.com/dns/what-is-cloud-dns).
For example: `A`, `AAAA`, `CNAME`, `MX`, or `TXT`.

@param [Boolean] skip_soa Do not automatically update the SOA record

serial number. See {#update} for details.

@param [Integer+, lambda, Proc] soa_serial A value (or a lambda or

Proc returning a value) for the new SOA record serial number. See
{#update} for details.

@yield [record] a block yielding each matching record @yieldparam [Record] record the record to be modified

@return [Google::Cloud::Dns::Change]

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
change = zone.modify "example.com.", "MX" do |mx|
  mx.ttl = 3600 # change only the TTL
end
# File lib/google/cloud/dns/zone.rb, line 653
def modify name, type, skip_soa: nil, soa_serial: nil, &block
  existing = records(name, type).all.to_a
  updated = existing.map(&:dup)
  updated.each(&block)
  update updated, existing, skip_soa: skip_soa, soa_serial: soa_serial
end
name() click to toggle source

User assigned name for this resource. Must be unique within the project. The name must be 1-32 characters long, must begin with a letter, end with a letter or digit, and only contain lowercase letters, digits or dashes.

# File lib/google/cloud/dns/zone.rb, line 74
def name
  @gapi.name
end
name_server_set() click to toggle source

Optionally specifies the NameServerSet for this ManagedZone. A NameServerSet is a set of DNS name servers that all host the same ManagedZones. Most users will leave this field unset.

# File lib/google/cloud/dns/zone.rb, line 106
def name_server_set
  @gapi.name_server_set
end
name_servers() click to toggle source

Delegate your managed_zone to these virtual name servers; defined by the server.

# File lib/google/cloud/dns/zone.rb, line 97
def name_servers
  Array(@gapi.name_servers)
end
new_record(name, type, ttl, data)
Alias for: record
record(name, type, ttl, data) click to toggle source

Creates a new, unsaved Record that can be added to a Zone. See {#update}.

@return [Google::Cloud::Dns::Record]

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
record = zone.record "example.com.", "A", 86400, ["1.2.3.4"]
zone.update record
# File lib/google/cloud/dns/zone.rb, line 321
def record name, type, ttl, data
  Google::Cloud::Dns::Record.new fqdn(name), type, ttl, data
end
Also aliased as: new_record
records(name = nil, type = nil, token: nil, max: nil) click to toggle source

Retrieves the list of records belonging to the zone. Records can be filtered by name and type. The name argument can be a subdomain (e.g., `www`) fragment for convenience, but notice that the retrieved record's domain name is always fully-qualified.

@param [String] name Return only records with this domain or subdomain

name.

@param [String] type Return only records with this [record

type](https://cloud.google.com/dns/what-is-cloud-dns). If present,
the `name` parameter must also be present.

@param [String] token A previously-returned page token representing

part of the larger set of results to view.

@param [Integer] max Maximum number of records to return.

@return [Array<Google::Cloud::Dns::Record>] (See

{Google::Cloud::Dns::Record::List})

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
records = zone.records
records.each do |record|
  puts record.name
end

@example Records can be filtered by name and type:

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
records = zone.records "www", "A"
records.first.name #=> "www.example.com."

@example Retrieve all records:

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
records = zone.records "example.com."

records.all do |record|
  puts record.name
end
# File lib/google/cloud/dns/zone.rb, line 297
def records name = nil, type = nil, token: nil, max: nil
  ensure_service!

  name = fqdn name if name

  gapi = service.list_records id, name, type, token: token, max: max
  Record::List.from_gapi gapi, self, name, type, max
end
Also aliased as: find_records
remove(name, type, skip_soa: nil, soa_serial: nil) click to toggle source

Removes records from the Zone. The records are looked up before they are removed. In order to update existing records, or add and remove records in the same transaction, use update.

This operation automatically updates the SOA record serial number unless prevented with the `skip_soa` option. See {#update} for details.

@param [String] name The owner of the record. For example:

`example.com.`.

@param [String] type The identifier of a [supported record

type](https://cloud.google.com/dns/what-is-cloud-dns).
For example: `A`, `AAAA`, `CNAME`, `MX`, or `TXT`.

@param [Boolean] skip_soa Do not automatically update the SOA record

serial number. See {#update} for details.

@param [Integer+, lambda, Proc] soa_serial A value (or a lambda or

Proc returning a value) for the new SOA record serial number. See
{#update} for details.

@return [Google::Cloud::Dns::Change]

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
change = zone.remove "example.com.", "A"
# File lib/google/cloud/dns/zone.rb, line 569
def remove name, type, skip_soa: nil, soa_serial: nil
  update [], records(name, type).all.to_a,
         skip_soa: skip_soa, soa_serial: soa_serial
end
replace(name, type, ttl, data, skip_soa: nil, soa_serial: nil) click to toggle source

Replaces existing records on the Zone. Records matching the `name` and `type` are replaced. In order to update existing records, or add and delete records in the same transaction, use update.

This operation automatically updates the SOA record serial number unless prevented with the `skip_soa` option. See {#update} for details.

@param [String] name The owner of the record. For example:

`example.com.`.

@param [String] type The identifier of a [supported record

type](https://cloud.google.com/dns/what-is-cloud-dns).
For example: `A`, `AAAA`, `CNAME`, `MX`, or `TXT`.

@param [Integer] ttl The number of seconds that the record can be

cached by resolvers.

@param [String, Array<String>] data The resource record data, as

determined by `type` and defined in [RFC 1035 (section
5)](http://tools.ietf.org/html/rfc1035#section-5) and [RFC 1034
(section 3.6.1)](http://tools.ietf.org/html/rfc1034#section-3.6.1).
For example: `192.0.2.1` or `example.com.`.

@param [Boolean] skip_soa Do not automatically update the SOA record

serial number. See {#update} for details.

@param [Integer+, lambda, Proc] soa_serial A value (or a lambda or

Proc returning a value) for the new SOA record serial number. See
{#update} for details.

@return [Google::Cloud::Dns::Change]

@example

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
change = zone.replace "example.com.", "A", 86400, ["5.6.7.8"]
# File lib/google/cloud/dns/zone.rb, line 610
def replace name, type, ttl, data, skip_soa: nil, soa_serial: nil
  update [record(name, type, ttl, data)],
         records(name, type).all.to_a,
         skip_soa: skip_soa, soa_serial: soa_serial
end
to_zonefile() click to toggle source

@private

# File lib/google/cloud/dns/zone.rb, line 617
def to_zonefile
  records.all.map(&:to_zonefile_records).flatten.join("\n")
end
update(additions = [], deletions = [], skip_soa: nil, soa_serial: nil) { |updater| ... } click to toggle source

Adds and removes Records from the zone. All changes are made in a single API request.

The best way to add, remove, and update multiple records in a single [transaction](cloud.google.com/dns/records) is with a block. See {Zone::Transaction}.

If the SOA record for the zone is not present in `additions` or `deletions` (and if present in one, it should be present in the other), it will be added to both, and its serial number will be incremented by adding `1`. This update to the SOA record can be prevented with the `skip_soa` option. To provide your own value or behavior for the new serial number, use the `soa_serial` option.

@param [Record, Array<Record>] additions The Record or array of

records to add.

@param [Record, Array<Record>] deletions The Record or array of

records to remove.

@param [Boolean] skip_soa Do not automatically update the SOA record

serial number.

@param [Integer, lambda, Proc] soa_serial A value (or a lambda or Proc

returning a value) for the new SOA record serial number.

@yield [tx] a block yielding a new transaction @yieldparam [Zone::Transaction] tx the transaction object

@return [Google::Cloud::Dns::Change]

@example Using a block:

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
change = zone.update do |tx|
  tx.add     "example.com.", "A",  86400, "1.2.3.4"
  tx.remove  "example.com.", "TXT"
  tx.replace "example.com.", "MX", 86400, ["10 mail1.example.com.",
                                           "20 mail2.example.com."]
  tx.modify "www.example.com.", "CNAME" do |cname|
    cname.ttl = 86400 # only change the TTL
  end
end

@example Or you can provide the record objects to add and remove:

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
new_record = zone.record "example.com.", "A", 86400, ["1.2.3.4"]
old_record = zone.record "example.com.", "A", 18600, ["1.2.3.4"]
change = zone.update [new_record], [old_record]

@example Using a lambda or Proc to update current SOA serial number:

require "google/cloud/dns"

dns = Google::Cloud::Dns.new
zone = dns.zone "example-com"
new_record = zone.record "example.com.", "A", 86400, ["1.2.3.4"]
change = zone.update new_record, soa_serial: lambda { |sn| sn + 10 }
# File lib/google/cloud/dns/zone.rb, line 468
def update additions = [], deletions = [], skip_soa: nil, soa_serial: nil
  # Handle only sending in options
  if additions.is_a?(::Hash) && deletions.empty? && options.empty?
    options = additions
    additions = []
  elsif deletions.is_a?(::Hash) && options.empty?
    options = deletions
    deletions = []
  end

  additions = Array additions
  deletions = Array deletions

  if block_given?
    updater = Zone::Transaction.new self
    yield updater
    additions += updater.additions
    deletions += updater.deletions
  end

  to_add    = additions - deletions
  to_remove = deletions - additions
  return nil if to_add.empty? && to_remove.empty?
  unless skip_soa || detect_soa(to_add) || detect_soa(to_remove)
    increment_soa to_add, to_remove, soa_serial
  end
  create_change to_add, to_remove
end

Protected Instance Methods

adjust_change_sort_order(order) click to toggle source
# File lib/google/cloud/dns/zone.rb, line 736
def adjust_change_sort_order order
  return nil if order.nil?
  if order.to_s.downcase.start_with? "d"
    "descending"
  else
    "ascending"
  end
end
create_change(additions, deletions) click to toggle source
# File lib/google/cloud/dns/zone.rb, line 702
def create_change additions, deletions
  ensure_service!
  gapi = service.create_change id, additions.map(&:to_gapi),
                               deletions.map(&:to_gapi)
  Change.from_gapi gapi, self
end
detect_soa(records) click to toggle source
# File lib/google/cloud/dns/zone.rb, line 719
def detect_soa records
  records.detect { |r| r.type == "SOA" }
end
ensure_service!() click to toggle source

Raise an error unless an active connection is available.

# File lib/google/cloud/dns/zone.rb, line 698
def ensure_service!
  raise "Must have active connection" unless service
end
increment_soa(to_add, to_remove, soa_serial) click to toggle source
# File lib/google/cloud/dns/zone.rb, line 709
def increment_soa to_add, to_remove, soa_serial
  current_soa = detect_soa records(dns, "SOA").all
  return false if current_soa.nil?
  updated_soa = current_soa.dup
  updated_soa.data[0] = replace_soa_serial updated_soa.data[0],
                                           soa_serial
  to_add << updated_soa
  to_remove << current_soa
end
replace_soa_serial(soa_data, soa_serial) click to toggle source
# File lib/google/cloud/dns/zone.rb, line 723
def replace_soa_serial soa_data, soa_serial
  soa_data = soa_data.split
  current_serial = soa_data[2].to_i
  soa_data[2] = if soa_serial && soa_serial.respond_to?(:call)
                  soa_serial.call current_serial
                elsif soa_serial
                  soa_serial.to_i
                else
                  current_serial + 1
                end
  soa_data.join " "
end