gcloud 0.3.1 → 0.4.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 +8 -8
- data/CHANGELOG.md +12 -0
- data/OVERVIEW.md +28 -0
- data/lib/gcloud.rb +46 -0
- data/lib/gcloud/bigquery.rb +15 -6
- data/lib/gcloud/bigquery/connection.rb +25 -12
- data/lib/gcloud/bigquery/table.rb +74 -7
- data/lib/gcloud/dns.rb +280 -0
- data/lib/gcloud/dns/change.rb +163 -0
- data/lib/gcloud/dns/change/list.rb +70 -0
- data/lib/gcloud/dns/connection.rb +164 -0
- data/lib/gcloud/dns/credentials.rb +29 -0
- data/lib/gcloud/dns/errors.rb +64 -0
- data/lib/gcloud/dns/importer.rb +195 -0
- data/lib/gcloud/dns/project.rb +291 -0
- data/lib/gcloud/dns/record.rb +152 -0
- data/lib/gcloud/dns/record/list.rb +92 -0
- data/lib/gcloud/dns/zone.rb +924 -0
- data/lib/gcloud/dns/zone/list.rb +75 -0
- data/lib/gcloud/dns/zone/transaction.rb +192 -0
- data/lib/gcloud/storage.rb +15 -6
- data/lib/gcloud/storage/bucket.rb +16 -7
- data/lib/gcloud/version.rb +1 -1
- metadata +29 -2
@@ -0,0 +1,152 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2015 Google Inc. All rights reserved.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require "gcloud/dns/record/list"
|
17
|
+
|
18
|
+
module Gcloud
|
19
|
+
module Dns
|
20
|
+
##
|
21
|
+
# = DNS Record
|
22
|
+
#
|
23
|
+
# Represents a set of DNS resource records (RRs) for a given #name and #type
|
24
|
+
# in a Zone. Since it is a value object, a newly created Record instance
|
25
|
+
# is transient until it is added to a Zone with Zone#update. Note that
|
26
|
+
# Zone#add and the Zone#update block parameter can be used instead of
|
27
|
+
# Zone#record or +Record.new+ to create new records.
|
28
|
+
#
|
29
|
+
# require "gcloud"
|
30
|
+
#
|
31
|
+
# gcloud = Gcloud.new
|
32
|
+
# dns = gcloud.dns
|
33
|
+
# zone = dns.zone "example-com"
|
34
|
+
#
|
35
|
+
# zone.records.count #=> 2
|
36
|
+
# record = zone.record "example.com.", "A", 86400, "1.2.3.4"
|
37
|
+
# zone.records.count #=> 2
|
38
|
+
# change = zone.update record
|
39
|
+
# zone.records.count #=> 3
|
40
|
+
#
|
41
|
+
#
|
42
|
+
class Record
|
43
|
+
##
|
44
|
+
# The owner of the record. For example: +example.com.+. (+String+)
|
45
|
+
attr_accessor :name
|
46
|
+
|
47
|
+
##
|
48
|
+
# The identifier of a {supported record type
|
49
|
+
# }[https://cloud.google.com/dns/what-is-cloud-dns#supported_record_types]
|
50
|
+
# . For example: +A+, +AAAA+, +CNAME+, +MX+, or +TXT+. (+String+)
|
51
|
+
attr_accessor :type
|
52
|
+
|
53
|
+
##
|
54
|
+
# The number of seconds that the record can be cached by resolvers.
|
55
|
+
# (+Integer+)
|
56
|
+
attr_accessor :ttl
|
57
|
+
|
58
|
+
##
|
59
|
+
# The array of resource record data, as determined by +type+ and defined
|
60
|
+
# in {RFC 1035 (section 5)}[http://tools.ietf.org/html/rfc1035#section-5]
|
61
|
+
# and {RFC
|
62
|
+
# 1034 (section 3.6.1)}[http://tools.ietf.org/html/rfc1034#section-3.6.1].
|
63
|
+
# For example: ["10 mail.example.com.", "20 mail2.example.com."].
|
64
|
+
# (+Array+ of +String+)
|
65
|
+
attr_accessor :data
|
66
|
+
|
67
|
+
##
|
68
|
+
# Creates a Record value object.
|
69
|
+
#
|
70
|
+
# === Parameters
|
71
|
+
#
|
72
|
+
# +name+::
|
73
|
+
# The owner of the record. For example: +example.com.+. (+String+)
|
74
|
+
# +type+::
|
75
|
+
# The identifier of a {supported record
|
76
|
+
# type}[https://cloud.google.com/dns/what-is-cloud-dns].
|
77
|
+
# For example: +A+, +AAAA+, +CNAME+, +MX+, or +TXT+. (+String+)
|
78
|
+
# +ttl+::
|
79
|
+
# The number of seconds that the record can be cached by resolvers.
|
80
|
+
# (+Integer+)
|
81
|
+
# +data+::
|
82
|
+
# The resource record data, as determined by +type+ and defined in {RFC
|
83
|
+
# 1035 (section 5)}[http://tools.ietf.org/html/rfc1035#section-5] and
|
84
|
+
# {RFC 1034
|
85
|
+
# (section 3.6.1)}[http://tools.ietf.org/html/rfc1034#section-3.6.1].
|
86
|
+
# For example: ["10 mail.example.com.", "20 mail2.example.com."].
|
87
|
+
# (+String+ or +Array+ of +String+)
|
88
|
+
#
|
89
|
+
def initialize name, type, ttl, data
|
90
|
+
fail ArgumentError, "name is required" unless name
|
91
|
+
fail ArgumentError, "type is required" unless type
|
92
|
+
fail ArgumentError, "ttl is required" unless ttl
|
93
|
+
fail ArgumentError, "data is required" unless data
|
94
|
+
@name = name.to_s
|
95
|
+
@type = type.to_s.upcase
|
96
|
+
@ttl = Integer(ttl)
|
97
|
+
@data = Array(data)
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Returns an array of strings in the zone file format, one
|
102
|
+
# for each element in the record's data array.
|
103
|
+
def to_zonefile_records #:nodoc:
|
104
|
+
data.map do |rrdata|
|
105
|
+
"#{name} #{ttl} IN #{type} #{rrdata}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Returns a deep copy of the record. Useful for updating records, since
|
111
|
+
# the original, unmodified record must be passed for deletion when using
|
112
|
+
# Zone#update.
|
113
|
+
def dup
|
114
|
+
other = super
|
115
|
+
other.data = data.map(&:dup)
|
116
|
+
other
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# New Record from a Google API Client object.
|
121
|
+
def self.from_gapi gapi #:nodoc:
|
122
|
+
new gapi["name"], gapi["type"], gapi["ttl"], gapi["rrdatas"]
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Convert the record object to a Google API hash.
|
127
|
+
def to_gapi #:nodoc:
|
128
|
+
{ "name" => name, "type" => type, "ttl" => ttl, "rrdatas" => data }
|
129
|
+
end
|
130
|
+
|
131
|
+
def hash #:nodoc:
|
132
|
+
[name, type, ttl, data].hash
|
133
|
+
end
|
134
|
+
|
135
|
+
def eql? other #:nodoc:
|
136
|
+
return false unless other.is_a? self.class
|
137
|
+
name == other.name && type == other.type &&
|
138
|
+
ttl == other.ttl && data == other.data
|
139
|
+
end
|
140
|
+
|
141
|
+
def == other #:nodoc:
|
142
|
+
self.eql? other
|
143
|
+
end
|
144
|
+
|
145
|
+
def <=> other #:nodoc:
|
146
|
+
return nil unless other.is_a? self.class
|
147
|
+
[name, type, ttl, data] <=>
|
148
|
+
[other.name, other.type, other.ttl, other.data]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2015 Google Inc. All rights reserved.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
module Gcloud
|
17
|
+
module Dns
|
18
|
+
class Record
|
19
|
+
##
|
20
|
+
# Record::List is a special case Array with additional values.
|
21
|
+
class List < DelegateClass(::Array)
|
22
|
+
##
|
23
|
+
# If not empty, indicates that there are more records that match
|
24
|
+
# the request and this value should be passed to continue.
|
25
|
+
attr_accessor :token
|
26
|
+
|
27
|
+
##
|
28
|
+
# Create a new Record::List with an array of Record instances.
|
29
|
+
def initialize arr = []
|
30
|
+
super arr
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Whether there a next page of records.
|
35
|
+
def next?
|
36
|
+
!token.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Retrieve the next page of records.
|
41
|
+
def next
|
42
|
+
return nil unless next?
|
43
|
+
ensure_zone!
|
44
|
+
@zone.records token: token
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Retrieves all records by repeatedly loading pages until #next? returns
|
49
|
+
# false. Returns the list instance for method chaining.
|
50
|
+
#
|
51
|
+
# === Example
|
52
|
+
#
|
53
|
+
# require "gcloud"
|
54
|
+
#
|
55
|
+
# gcloud = Gcloud.new
|
56
|
+
# dns = gcloud.dns
|
57
|
+
# zone = dns.zone "example-com"
|
58
|
+
# records = zone.records.all # Load all pages of records
|
59
|
+
#
|
60
|
+
def all
|
61
|
+
while next?
|
62
|
+
next_records = self.next
|
63
|
+
push(*next_records)
|
64
|
+
self.token = next_records.token
|
65
|
+
end
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# New Records::List from a response object.
|
71
|
+
def self.from_response resp, zone #:nodoc:
|
72
|
+
records = new(Array(resp.data["rrsets"]).map do |gapi_object|
|
73
|
+
Record.from_gapi gapi_object
|
74
|
+
end)
|
75
|
+
records.instance_eval do
|
76
|
+
@token = resp.data["nextPageToken"]
|
77
|
+
@zone = zone
|
78
|
+
end
|
79
|
+
records
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
##
|
85
|
+
# Raise an error unless an active connection is available.
|
86
|
+
def ensure_zone!
|
87
|
+
fail "Must have active connection" unless @zone
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,924 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2015 Google Inc. All rights reserved.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require "gcloud/dns/change"
|
17
|
+
require "gcloud/dns/zone/transaction"
|
18
|
+
require "gcloud/dns/zone/list"
|
19
|
+
require "gcloud/dns/record"
|
20
|
+
require "gcloud/dns/importer"
|
21
|
+
require "time"
|
22
|
+
|
23
|
+
module Gcloud
|
24
|
+
module Dns
|
25
|
+
##
|
26
|
+
# = DNS Zone
|
27
|
+
#
|
28
|
+
# The managed zone is the container for DNS records for the same DNS name
|
29
|
+
# suffix and has a set of name servers that accept and responds to queries.
|
30
|
+
# A project can have multiple managed zones, but they must each have a
|
31
|
+
# unique name.
|
32
|
+
#
|
33
|
+
# require "gcloud"
|
34
|
+
#
|
35
|
+
# gcloud = Gcloud.new
|
36
|
+
# dns = gcloud.dns
|
37
|
+
# zone = dns.zone "example-com"
|
38
|
+
# zone.records.each do |record|
|
39
|
+
# puts record.name
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# For more information, see {Managing
|
43
|
+
# Zones}[https://cloud.google.com/dns/zones/].
|
44
|
+
#
|
45
|
+
class Zone
|
46
|
+
##
|
47
|
+
# The Connection object.
|
48
|
+
attr_accessor :connection #:nodoc:
|
49
|
+
|
50
|
+
##
|
51
|
+
# The Google API Client object.
|
52
|
+
attr_accessor :gapi #:nodoc:
|
53
|
+
|
54
|
+
##
|
55
|
+
# Create an empty Zone object.
|
56
|
+
def initialize #:nodoc:
|
57
|
+
@connection = nil
|
58
|
+
@gapi = {}
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Unique identifier for the resource; defined by the server.
|
63
|
+
#
|
64
|
+
def id
|
65
|
+
@gapi["id"]
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# User assigned name for this resource. Must be unique within the project.
|
70
|
+
# The name must be 1-32 characters long, must begin with a letter, end
|
71
|
+
# with a letter or digit, and only contain lowercase letters, digits or
|
72
|
+
# dashes.
|
73
|
+
#
|
74
|
+
def name
|
75
|
+
@gapi["name"]
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# The DNS name of this managed zone, for instance "example.com.".
|
80
|
+
#
|
81
|
+
def dns
|
82
|
+
@gapi["dnsName"]
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# A string of at most 1024 characters associated with this resource for
|
87
|
+
# the user's convenience. Has no effect on the managed zone's function.
|
88
|
+
#
|
89
|
+
def description
|
90
|
+
@gapi["description"]
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Delegate your managed_zone to these virtual name servers; defined by the
|
95
|
+
# server.
|
96
|
+
#
|
97
|
+
def name_servers
|
98
|
+
Array(@gapi["nameServers"])
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Optionally specifies the NameServerSet for this ManagedZone. A
|
103
|
+
# NameServerSet is a set of DNS name servers that all host the same
|
104
|
+
# ManagedZones. Most users will leave this field unset.
|
105
|
+
#
|
106
|
+
def name_server_set
|
107
|
+
@gapi["nameServerSet"]
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# The time that this resource was created on the server.
|
112
|
+
#
|
113
|
+
def created_at
|
114
|
+
Time.parse @gapi["creationTime"]
|
115
|
+
rescue
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Permanently deletes the zone.
|
121
|
+
#
|
122
|
+
# === Parameters
|
123
|
+
#
|
124
|
+
# +options+::
|
125
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
126
|
+
# <code>options[:force]</code>::
|
127
|
+
# If +true+, ensures the deletion of the zone by first deleting all
|
128
|
+
# records. If +false+ and the zone contains non-essential records, the
|
129
|
+
# request will fail. Default is +false+. (+Boolean+)
|
130
|
+
#
|
131
|
+
# === Returns
|
132
|
+
#
|
133
|
+
# +true+ if the zone was deleted.
|
134
|
+
#
|
135
|
+
# === Examples
|
136
|
+
#
|
137
|
+
# require "gcloud"
|
138
|
+
#
|
139
|
+
# gcloud = Gcloud.new
|
140
|
+
# dns = gcloud.dns
|
141
|
+
# zone = dns.zone "example-com"
|
142
|
+
# zone.delete
|
143
|
+
#
|
144
|
+
# The zone can be forcefully deleted with the +force+ option:
|
145
|
+
#
|
146
|
+
# require "gcloud"
|
147
|
+
#
|
148
|
+
# gcloud = Gcloud.new
|
149
|
+
# dns = gcloud.dns
|
150
|
+
# zone = dns.zone "example-com"
|
151
|
+
# zone.delete force: true
|
152
|
+
#
|
153
|
+
def delete options = {}
|
154
|
+
clear! if options[:force]
|
155
|
+
|
156
|
+
ensure_connection!
|
157
|
+
resp = connection.delete_zone id
|
158
|
+
if resp.success?
|
159
|
+
true
|
160
|
+
else
|
161
|
+
fail ApiError.from_response(resp)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# Removes non-essential records from the zone. Only NS and SOA records
|
167
|
+
# will be kept.
|
168
|
+
#
|
169
|
+
# === Examples
|
170
|
+
#
|
171
|
+
# require "gcloud"
|
172
|
+
#
|
173
|
+
# gcloud = Gcloud.new
|
174
|
+
# dns = gcloud.dns
|
175
|
+
# zone = dns.zone "example-com"
|
176
|
+
# zone.clear!
|
177
|
+
#
|
178
|
+
def clear!
|
179
|
+
non_essential = records.all.reject { |r| %w(SOA NS).include?(r.type) }
|
180
|
+
change = update [], non_essential
|
181
|
+
change.wait_until_done! unless change.nil?
|
182
|
+
end
|
183
|
+
|
184
|
+
##
|
185
|
+
# Retrieves an existing change by id.
|
186
|
+
#
|
187
|
+
# === Parameters
|
188
|
+
#
|
189
|
+
# +change_id+::
|
190
|
+
# The id of a change. (+String+)
|
191
|
+
#
|
192
|
+
# === Returns
|
193
|
+
#
|
194
|
+
# Gcloud::Dns::Change or +nil+ if the change does not exist
|
195
|
+
#
|
196
|
+
# === Example
|
197
|
+
#
|
198
|
+
# require "gcloud"
|
199
|
+
#
|
200
|
+
# gcloud = Gcloud.new
|
201
|
+
# dns = gcloud.dns
|
202
|
+
# zone = dns.zone "example-com"
|
203
|
+
# change = zone.change "2"
|
204
|
+
# if change
|
205
|
+
# puts "#{change.id} - #{change.started_at} - #{change.status}"
|
206
|
+
# end
|
207
|
+
#
|
208
|
+
def change change_id
|
209
|
+
ensure_connection!
|
210
|
+
resp = connection.get_change id, change_id
|
211
|
+
if resp.success?
|
212
|
+
Change.from_gapi resp.data, self
|
213
|
+
else
|
214
|
+
nil
|
215
|
+
end
|
216
|
+
end
|
217
|
+
alias_method :find_change, :change
|
218
|
+
alias_method :get_change, :change
|
219
|
+
|
220
|
+
##
|
221
|
+
# Retrieves the list of changes belonging to the zone.
|
222
|
+
#
|
223
|
+
# === Parameters
|
224
|
+
#
|
225
|
+
# +options+::
|
226
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
227
|
+
# <code>options[:token]</code>::
|
228
|
+
# A previously-returned page token representing part of the larger set
|
229
|
+
# of results to view. (+String+)
|
230
|
+
# <code>options[:max]</code>::
|
231
|
+
# Maximum number of changes to return. (+Integer+)
|
232
|
+
# <code>options[:order]</code>::
|
233
|
+
# Sort the changes by change sequence. (+Symbol+ or +String+)
|
234
|
+
#
|
235
|
+
# Acceptable values are:
|
236
|
+
# * +asc+ - Sort by ascending change sequence
|
237
|
+
# * +desc+ - Sort by descending change sequence
|
238
|
+
#
|
239
|
+
# === Returns
|
240
|
+
#
|
241
|
+
# Array of Gcloud::Dns::Change (Gcloud::Dns::Change::List)
|
242
|
+
#
|
243
|
+
# === Examples
|
244
|
+
#
|
245
|
+
# require "gcloud"
|
246
|
+
#
|
247
|
+
# gcloud = Gcloud.new
|
248
|
+
# dns = gcloud.dns
|
249
|
+
# zone = dns.zone "example-com"
|
250
|
+
# changes = zone.changes
|
251
|
+
# changes.each do |change|
|
252
|
+
# puts "#{change.id} - #{change.started_at} - #{change.status}"
|
253
|
+
# end
|
254
|
+
#
|
255
|
+
# The changes can be sorted by change sequence:
|
256
|
+
#
|
257
|
+
# require "gcloud"
|
258
|
+
#
|
259
|
+
# gcloud = Gcloud.new
|
260
|
+
# dns = gcloud.dns
|
261
|
+
# zone = dns.zone "example-com"
|
262
|
+
# changes = zone.changes order: :desc
|
263
|
+
#
|
264
|
+
# If you have a significant number of changes, you may need to paginate
|
265
|
+
# through them: (See Gcloud::Dns::Change::List)
|
266
|
+
#
|
267
|
+
# require "gcloud"
|
268
|
+
#
|
269
|
+
# gcloud = Gcloud.new
|
270
|
+
# dns = gcloud.dns
|
271
|
+
# zone = dns.zone "example-com"
|
272
|
+
# changes = zone.changes
|
273
|
+
# loop do
|
274
|
+
# changes.each do |change|
|
275
|
+
# puts "#{change.name} - #{change.status}"
|
276
|
+
# end
|
277
|
+
# break unless changes.next?
|
278
|
+
# changes = changes.next
|
279
|
+
# end
|
280
|
+
#
|
281
|
+
def changes options = {}
|
282
|
+
ensure_connection!
|
283
|
+
# Fix the sort options
|
284
|
+
options[:order] = adjust_change_sort_order options[:order]
|
285
|
+
options[:sort] = "changeSequence" if options[:order]
|
286
|
+
# Continue with the API call
|
287
|
+
resp = connection.list_changes id, options
|
288
|
+
if resp.success?
|
289
|
+
Change::List.from_response resp, self
|
290
|
+
else
|
291
|
+
fail ApiError.from_response(resp)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
alias_method :find_changes, :changes
|
295
|
+
|
296
|
+
##
|
297
|
+
# Retrieves the list of records belonging to the zone.
|
298
|
+
#
|
299
|
+
# === Parameters
|
300
|
+
#
|
301
|
+
# +name+::
|
302
|
+
# Return only records with this domain or subdomain name. (+String+)
|
303
|
+
# +type+::
|
304
|
+
# Return only records with this {record
|
305
|
+
# type}[https://cloud.google.com/dns/what-is-cloud-dns].
|
306
|
+
# If present, the +name+ parameter must also be present. (+String+)
|
307
|
+
# +options+::
|
308
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
309
|
+
# <code>options[:token]</code>::
|
310
|
+
# A previously-returned page token representing part of the larger set
|
311
|
+
# of results to view. (+String+)
|
312
|
+
# <code>options[:max]</code>::
|
313
|
+
# Maximum number of records to return. (+Integer+)
|
314
|
+
#
|
315
|
+
# === Returns
|
316
|
+
#
|
317
|
+
# Array of Gcloud::Dns::Record (Gcloud::Dns::Record::List)
|
318
|
+
#
|
319
|
+
# === Examples
|
320
|
+
#
|
321
|
+
# require "gcloud"
|
322
|
+
#
|
323
|
+
# gcloud = Gcloud.new
|
324
|
+
# dns = gcloud.dns
|
325
|
+
# zone = dns.zone "example-com"
|
326
|
+
# records = zone.records
|
327
|
+
# records.each do |record|
|
328
|
+
# puts record.name
|
329
|
+
# end
|
330
|
+
#
|
331
|
+
# Records can be filtered by name and type. The name argument can be a
|
332
|
+
# subdomain (e.g., +www+) fragment for convenience, but notice that the
|
333
|
+
# retrieved record's domain name is always fully-qualified.
|
334
|
+
#
|
335
|
+
# require "gcloud"
|
336
|
+
#
|
337
|
+
# gcloud = Gcloud.new
|
338
|
+
# dns = gcloud.dns
|
339
|
+
# zone = dns.zone "example-com"
|
340
|
+
# records = zone.records "www", "A"
|
341
|
+
# records.first.name #=> "www.example.com."
|
342
|
+
#
|
343
|
+
# If you have a significant number of records, you may need to paginate
|
344
|
+
# through them: (See Gcloud::Dns::Record::List)
|
345
|
+
#
|
346
|
+
# require "gcloud"
|
347
|
+
#
|
348
|
+
# gcloud = Gcloud.new
|
349
|
+
# dns = gcloud.dns
|
350
|
+
# zone = dns.zone "example-com"
|
351
|
+
# records = zone.records "example.com."
|
352
|
+
# loop do
|
353
|
+
# records.each do |record|
|
354
|
+
# puts record.name
|
355
|
+
# end
|
356
|
+
# break unless records.next?
|
357
|
+
# records = records.next
|
358
|
+
# end
|
359
|
+
#
|
360
|
+
# Or, instead of paging manually, you can retrieve all of the pages in a
|
361
|
+
# single call: (See Gcloud::Dns::Record::List#all)
|
362
|
+
#
|
363
|
+
# require "gcloud"
|
364
|
+
#
|
365
|
+
# gcloud = Gcloud.new
|
366
|
+
# dns = gcloud.dns
|
367
|
+
# zone = dns.zone "example-com"
|
368
|
+
# records = zone.records.all
|
369
|
+
#
|
370
|
+
def records name = nil, type = nil, options = {}
|
371
|
+
ensure_connection!
|
372
|
+
|
373
|
+
options = build_records_options name, type, options
|
374
|
+
|
375
|
+
resp = connection.list_records id, options
|
376
|
+
if resp.success?
|
377
|
+
Record::List.from_response resp, self
|
378
|
+
else
|
379
|
+
fail ApiError.from_response(resp)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
alias_method :find_records, :records
|
383
|
+
|
384
|
+
##
|
385
|
+
# Creates a new, unsaved Record that can be added to a Zone.
|
386
|
+
#
|
387
|
+
# === Returns
|
388
|
+
#
|
389
|
+
# Gcloud::Dns::Record
|
390
|
+
#
|
391
|
+
# === Example
|
392
|
+
#
|
393
|
+
# require "gcloud"
|
394
|
+
#
|
395
|
+
# gcloud = Gcloud.new
|
396
|
+
# dns = gcloud.dns
|
397
|
+
# zone = dns.zone "example-com"
|
398
|
+
# record = zone.record "example.com.", "A", 86400, ["1.2.3.4"]
|
399
|
+
# zone.add record
|
400
|
+
#
|
401
|
+
def record name, type, ttl, data
|
402
|
+
Gcloud::Dns::Record.new fqdn(name), type, ttl, data
|
403
|
+
end
|
404
|
+
alias_method :new_record, :record
|
405
|
+
|
406
|
+
##
|
407
|
+
# Exports the zone to a local {DNS zone
|
408
|
+
# file}[https://en.wikipedia.org/wiki/Zone_file].
|
409
|
+
#
|
410
|
+
# === Parameters
|
411
|
+
#
|
412
|
+
# +path+::
|
413
|
+
# The path on the local file system to write the data to.
|
414
|
+
# The path provided must be writable. (+String+)
|
415
|
+
#
|
416
|
+
# === Returns
|
417
|
+
#
|
418
|
+
# +::File+ object on the local file system
|
419
|
+
#
|
420
|
+
# === Examples
|
421
|
+
#
|
422
|
+
# require "gcloud"
|
423
|
+
#
|
424
|
+
# gcloud = Gcloud.new
|
425
|
+
# dns = gcloud.dns
|
426
|
+
# zone = dns.zone "example-com"
|
427
|
+
#
|
428
|
+
# zone.export "path/to/db.example.com"
|
429
|
+
#
|
430
|
+
def export path
|
431
|
+
File.open path, "w" do |f|
|
432
|
+
f.write to_zonefile
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
##
|
437
|
+
# Imports resource records from a {DNS zone
|
438
|
+
# file}[https://en.wikipedia.org/wiki/Zone_file], adding the new records
|
439
|
+
# to the zone, without removing any existing records from the zone.
|
440
|
+
#
|
441
|
+
# Because the Google Cloud DNS API only accepts a single resource record
|
442
|
+
# for each +name+ and +type+ combination (with multiple +data+ elements),
|
443
|
+
# the zone file's records are merged as necessary. During this merge, the
|
444
|
+
# lowest +ttl+ of the merged records is used. If none of the merged
|
445
|
+
# records have a +ttl+ value, the zone file's global TTL is used for the
|
446
|
+
# record.
|
447
|
+
#
|
448
|
+
# The zone file's SOA and NS records are not imported, because the zone
|
449
|
+
# was given SOA and NS records when it was created. These generated
|
450
|
+
# records point to Cloud DNS name servers.
|
451
|
+
#
|
452
|
+
# This operation automatically updates the SOA record serial number unless
|
453
|
+
# prevented with the +skip_soa+ option. See #update for details.
|
454
|
+
#
|
455
|
+
# The Google Cloud DNS service requires that record names and data use
|
456
|
+
# fully-qualified addresses. The @ symbol is not accepted, nor are
|
457
|
+
# unqualified subdomain addresses like www. If your zone file contains
|
458
|
+
# such values, you may need to pre-process it in order for the import
|
459
|
+
# operation to succeed.
|
460
|
+
#
|
461
|
+
# === Parameters
|
462
|
+
#
|
463
|
+
# +path_or_io+::
|
464
|
+
# The path to a zone file on the filesystem, or an IO instance from
|
465
|
+
# which zone file data can be read. (+String+ or +IO+)
|
466
|
+
# +options+::
|
467
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
468
|
+
# <code>options[:only]</code>::
|
469
|
+
# Include only records of this type or types. (+String+ or +Array+)
|
470
|
+
# <code>options[:except]</code>::
|
471
|
+
# Exclude records of this type or types. (+String+ or +Array+)
|
472
|
+
# <code>options[:skip_soa]</code>::
|
473
|
+
# Do not automatically update the SOA record serial number. See #update
|
474
|
+
# for details. (+Boolean+)
|
475
|
+
# <code>options[:soa_serial]</code>::
|
476
|
+
# A value (or a lambda or Proc returning a value) for the new SOA record
|
477
|
+
# serial number. See #update for details. (+Integer+, lambda, or +Proc+)
|
478
|
+
#
|
479
|
+
# === Returns
|
480
|
+
#
|
481
|
+
# A new Change adding the imported Record instances.
|
482
|
+
#
|
483
|
+
# === Example
|
484
|
+
#
|
485
|
+
# require "gcloud"
|
486
|
+
#
|
487
|
+
# gcloud = Gcloud.new
|
488
|
+
# dns = gcloud.dns
|
489
|
+
# zone = dns.zone "example-com"
|
490
|
+
# change = zone.import "path/to/db.example.com"
|
491
|
+
#
|
492
|
+
def import path_or_io, options = {}
|
493
|
+
options[:except] = Array(options[:except]).map(&:to_s).map(&:upcase)
|
494
|
+
options[:except] = (options[:except] + %w(SOA NS)).uniq
|
495
|
+
additions = Gcloud::Dns::Importer.new(self, path_or_io).records(options)
|
496
|
+
update additions, []
|
497
|
+
end
|
498
|
+
|
499
|
+
# rubocop:disable all
|
500
|
+
# Disabled rubocop because this complexity cannot easily be avoided.
|
501
|
+
|
502
|
+
##
|
503
|
+
# Adds and removes Records from the zone. All changes are made in a single
|
504
|
+
# API request.
|
505
|
+
#
|
506
|
+
# If the SOA record for the zone is not present in +additions+ or
|
507
|
+
# +deletions+ (and if present in one, it should be present in the other),
|
508
|
+
# it will be added to both, and its serial number will be incremented by
|
509
|
+
# adding +1+. This update to the SOA record can be prevented with the
|
510
|
+
# +skip_soa+ option. To provide your own value or behavior for the new
|
511
|
+
# serial number, use the +soa_serial+ option.
|
512
|
+
#
|
513
|
+
# === Parameters
|
514
|
+
#
|
515
|
+
# +additions+::
|
516
|
+
# The Record or array of records to add. (Record or +Array+)
|
517
|
+
# +deletions+::
|
518
|
+
# The Record or array of records to remove. (Record or +Array+)
|
519
|
+
# +options+::
|
520
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
521
|
+
# <code>options[:skip_soa]</code>::
|
522
|
+
# Do not automatically update the SOA record serial number. (+Boolean+)
|
523
|
+
# <code>options[:soa_serial]</code>::
|
524
|
+
# A value (or a lambda or Proc returning a value) for the new SOA record
|
525
|
+
# serial number. (+Integer+, lambda, or +Proc+)
|
526
|
+
#
|
527
|
+
# === Returns
|
528
|
+
#
|
529
|
+
# Gcloud::Dns::Change
|
530
|
+
#
|
531
|
+
# === Examples
|
532
|
+
#
|
533
|
+
# The best way to add, remove, and update multiple records in a single
|
534
|
+
# {transaction}[https://cloud.google.com/dns/records] is with a block. See
|
535
|
+
# Zone::Transaction.
|
536
|
+
#
|
537
|
+
# require "gcloud"
|
538
|
+
#
|
539
|
+
# gcloud = Gcloud.new
|
540
|
+
# dns = gcloud.dns
|
541
|
+
# zone = dns.zone "example-com"
|
542
|
+
# change = zone.update do |tx|
|
543
|
+
# tx.add "example.com.", "A", 86400, "1.2.3.4"
|
544
|
+
# tx.remove "example.com.", "TXT"
|
545
|
+
# tx.replace "example.com.", "MX", 86400, ["10 mail1.example.com.",
|
546
|
+
# "20 mail2.example.com."]
|
547
|
+
# tx.modify "www.example.com.", "CNAME" do |cname|
|
548
|
+
# cname.ttl = 86400 # only change the TTL
|
549
|
+
# end
|
550
|
+
# end
|
551
|
+
#
|
552
|
+
# Or you can provide the record objects to add and remove.
|
553
|
+
#
|
554
|
+
# require "gcloud"
|
555
|
+
#
|
556
|
+
# gcloud = Gcloud.new
|
557
|
+
# dns = gcloud.dns
|
558
|
+
# zone = dns.zone "example-com"
|
559
|
+
# new_record = zone.record "example.com.", "A", 86400, ["1.2.3.4"]
|
560
|
+
# old_record = zone.record "example.com.", "A", 18600, ["1.2.3.4"]
|
561
|
+
# change = zone.update [new_record], [old_record]
|
562
|
+
#
|
563
|
+
# You can provide a lambda or Proc that receives the current SOA record
|
564
|
+
# serial number and returns a new serial number.
|
565
|
+
#
|
566
|
+
# require "gcloud"
|
567
|
+
#
|
568
|
+
# gcloud = Gcloud.new
|
569
|
+
# dns = gcloud.dns
|
570
|
+
# zone = dns.zone "example-com"
|
571
|
+
# new_record = zone.record "example.com.", "A", 86400, ["1.2.3.4"]
|
572
|
+
# change = zone.update new_record, soa_serial: lambda { |sn| sn + 10 }
|
573
|
+
#
|
574
|
+
def update additions = [], deletions = [], options = {}
|
575
|
+
# Handle only sending in options
|
576
|
+
if additions.is_a?(::Hash) && deletions.empty? && options.empty?
|
577
|
+
options = additions
|
578
|
+
additions = []
|
579
|
+
elsif deletions.is_a?(::Hash) && options.empty?
|
580
|
+
options = deletions
|
581
|
+
deletions = []
|
582
|
+
end
|
583
|
+
|
584
|
+
additions = Array additions
|
585
|
+
deletions = Array deletions
|
586
|
+
|
587
|
+
if block_given?
|
588
|
+
updater = Zone::Transaction.new self
|
589
|
+
yield updater
|
590
|
+
additions += updater.additions
|
591
|
+
deletions += updater.deletions
|
592
|
+
end
|
593
|
+
|
594
|
+
to_add = additions - deletions
|
595
|
+
to_remove = deletions - additions
|
596
|
+
return nil if to_add.empty? && to_remove.empty?
|
597
|
+
unless options[:skip_soa] || detect_soa(to_add) || detect_soa(to_remove)
|
598
|
+
increment_soa to_add, to_remove, options[:soa_serial]
|
599
|
+
end
|
600
|
+
create_change to_add, to_remove
|
601
|
+
end
|
602
|
+
|
603
|
+
# rubocop:enable all
|
604
|
+
|
605
|
+
##
|
606
|
+
# Adds a record to the Zone. In order to update existing records, or add
|
607
|
+
# and delete records in the same transaction, use #update.
|
608
|
+
#
|
609
|
+
# This operation automatically updates the SOA record serial number unless
|
610
|
+
# prevented with the +skip_soa+ option. See #update for details.
|
611
|
+
#
|
612
|
+
# === Parameters
|
613
|
+
#
|
614
|
+
# +name+::
|
615
|
+
# The owner of the record. For example: +example.com.+. (+String+)
|
616
|
+
# +type+::
|
617
|
+
# The identifier of a {supported record
|
618
|
+
# type}[https://cloud.google.com/dns/what-is-cloud-dns].
|
619
|
+
# For example: +A+, +AAAA+, +CNAME+, +MX+, or +TXT+. (+String+)
|
620
|
+
# +ttl+::
|
621
|
+
# The number of seconds that the record can be cached by resolvers.
|
622
|
+
# (+Integer+)
|
623
|
+
# +data+::
|
624
|
+
# The resource record data, as determined by +type+ and defined in {RFC
|
625
|
+
# 1035 (section 5)}[http://tools.ietf.org/html/rfc1035#section-5] and
|
626
|
+
# {RFC 1034
|
627
|
+
# (section 3.6.1)}[http://tools.ietf.org/html/rfc1034#section-3.6.1].
|
628
|
+
# For example: +192.0.2.1+ or +example.com.+. (+String+ or +Array+ of
|
629
|
+
# +String+)
|
630
|
+
# +options+::
|
631
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
632
|
+
# <code>options[:skip_soa]</code>::
|
633
|
+
# Do not automatically update the SOA record serial number. See #update
|
634
|
+
# for details. (+Boolean+)
|
635
|
+
# <code>options[:soa_serial]</code>::
|
636
|
+
# A value (or a lambda or Proc returning a value) for the new SOA record
|
637
|
+
# serial number. See #update for details. (+Integer+, lambda, or +Proc+)
|
638
|
+
#
|
639
|
+
# === Returns
|
640
|
+
#
|
641
|
+
# Gcloud::Dns::Change
|
642
|
+
#
|
643
|
+
# === Example
|
644
|
+
#
|
645
|
+
# require "gcloud"
|
646
|
+
#
|
647
|
+
# gcloud = Gcloud.new
|
648
|
+
# dns = gcloud.dns
|
649
|
+
# zone = dns.zone "example-com"
|
650
|
+
# change = zone.add "example.com.", "A", 86400, ["1.2.3.4"]
|
651
|
+
#
|
652
|
+
def add name, type, ttl, data, options = {}
|
653
|
+
update [record(name, type, ttl, data)], [], options
|
654
|
+
end
|
655
|
+
|
656
|
+
##
|
657
|
+
# Removes records from the Zone. The records are looked up before they are
|
658
|
+
# removed. In order to update existing records, or add and remove records
|
659
|
+
# in the same transaction, use #update.
|
660
|
+
#
|
661
|
+
# This operation automatically updates the SOA record serial number unless
|
662
|
+
# prevented with the +skip_soa+ option. See #update for details.
|
663
|
+
#
|
664
|
+
# === Parameters
|
665
|
+
#
|
666
|
+
# +name+::
|
667
|
+
# The owner of the record. For example: +example.com.+. (+String+)
|
668
|
+
# +type+::
|
669
|
+
# The identifier of a {supported record
|
670
|
+
# type}[https://cloud.google.com/dns/what-is-cloud-dns].
|
671
|
+
# For example: +A+, +AAAA+, +CNAME+, +MX+, or +TXT+. (+String+)
|
672
|
+
# +options+::
|
673
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
674
|
+
# <code>options[:skip_soa]</code>::
|
675
|
+
# Do not automatically update the SOA record serial number. See #update
|
676
|
+
# for details. (+Boolean+)
|
677
|
+
# <code>options[:soa_serial]</code>::
|
678
|
+
# A value (or a lambda or Proc returning a value) for the new SOA record
|
679
|
+
# serial number. See #update for details. (+Integer+, lambda, or +Proc+)
|
680
|
+
#
|
681
|
+
# === Returns
|
682
|
+
#
|
683
|
+
# Gcloud::Dns::Change
|
684
|
+
#
|
685
|
+
# === Example
|
686
|
+
#
|
687
|
+
# require "gcloud"
|
688
|
+
#
|
689
|
+
# gcloud = Gcloud.new
|
690
|
+
# dns = gcloud.dns
|
691
|
+
# zone = dns.zone "example-com"
|
692
|
+
# change = zone.remove "example.com.", "A"
|
693
|
+
#
|
694
|
+
def remove name, type, options = {}
|
695
|
+
update [], records(name: name, type: type).all.to_a, options
|
696
|
+
end
|
697
|
+
|
698
|
+
##
|
699
|
+
# Replaces existing records on the Zone. Records matching the +name+ and
|
700
|
+
# +type+ are replaced. In order to update existing records, or add and
|
701
|
+
# delete records in the same transaction, use #update.
|
702
|
+
#
|
703
|
+
# This operation automatically updates the SOA record serial number unless
|
704
|
+
# prevented with the +skip_soa+ option. See #update for details.
|
705
|
+
#
|
706
|
+
# === Parameters
|
707
|
+
#
|
708
|
+
# +name+::
|
709
|
+
# The owner of the record. For example: +example.com.+. (+String+)
|
710
|
+
# +type+::
|
711
|
+
# The identifier of a {supported record
|
712
|
+
# type}[https://cloud.google.com/dns/what-is-cloud-dns].
|
713
|
+
# For example: +A+, +AAAA+, +CNAME+, +MX+, or +TXT+. (+String+)
|
714
|
+
# +ttl+::
|
715
|
+
# The number of seconds that the record can be cached by resolvers.
|
716
|
+
# (+Integer+)
|
717
|
+
# +data+::
|
718
|
+
# The resource record data, as determined by +type+ and defined in
|
719
|
+
# {RFC 1035 (section 5)}[http://tools.ietf.org/html/rfc1035#section-5]
|
720
|
+
# and {RFC 1034 (section
|
721
|
+
# 3.6.1)}[http://tools.ietf.org/html/rfc1034#section-3.6.1]. For
|
722
|
+
# example: +192.0.2.1+ or +example.com.+. (+String+ or +Array+ of
|
723
|
+
# +String+)
|
724
|
+
# +options+::
|
725
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
726
|
+
# <code>options[:skip_soa]</code>::
|
727
|
+
# Do not automatically update the SOA record serial number. See #update
|
728
|
+
# for details. (+Boolean+)
|
729
|
+
# <code>options[:soa_serial]</code>::
|
730
|
+
# A value (or a lambda or Proc returning a value) for the new SOA record
|
731
|
+
# serial number. See #update for details. (+Integer+, lambda, or +Proc+)
|
732
|
+
#
|
733
|
+
# === Returns
|
734
|
+
#
|
735
|
+
# Gcloud::Dns::Change
|
736
|
+
#
|
737
|
+
# === Example
|
738
|
+
#
|
739
|
+
# require "gcloud"
|
740
|
+
#
|
741
|
+
# gcloud = Gcloud.new
|
742
|
+
# dns = gcloud.dns
|
743
|
+
# zone = dns.zone "example-com"
|
744
|
+
# change = zone.replace "example.com.", "A", 86400, ["5.6.7.8"]
|
745
|
+
#
|
746
|
+
def replace name, type, ttl, data, options = {}
|
747
|
+
update [record(name, type, ttl, data)],
|
748
|
+
records(name: name, type: type).all.to_a,
|
749
|
+
options
|
750
|
+
end
|
751
|
+
|
752
|
+
def to_zonefile #:nodoc:
|
753
|
+
records.all.map(&:to_zonefile_records).flatten.join("\n")
|
754
|
+
end
|
755
|
+
|
756
|
+
##
|
757
|
+
# Modifies records on the Zone. Records matching the +name+ and +type+ are
|
758
|
+
# yielded to the block where they can be modified.
|
759
|
+
#
|
760
|
+
# This operation automatically updates the SOA record serial number unless
|
761
|
+
# prevented with the +skip_soa+ option. See #update for details.
|
762
|
+
#
|
763
|
+
# === Parameters
|
764
|
+
#
|
765
|
+
# +name+::
|
766
|
+
# The owner of the record. For example: +example.com.+. (+String+)
|
767
|
+
# +type+::
|
768
|
+
# The identifier of a {supported record
|
769
|
+
# type}[https://cloud.google.com/dns/what-is-cloud-dns].
|
770
|
+
# For example: +A+, +AAAA+, +CNAME+, +MX+, or +TXT+. (+String+)
|
771
|
+
# +options+::
|
772
|
+
# An optional Hash for controlling additional behavior. (+Hash+)
|
773
|
+
# <code>options[:skip_soa]</code>::
|
774
|
+
# Do not automatically update the SOA record serial number. See #update
|
775
|
+
# for details. (+Boolean+)
|
776
|
+
# <code>options[:soa_serial]</code>::
|
777
|
+
# A value (or a lambda or Proc returning a value) for the new SOA record
|
778
|
+
# serial number. See #update for details. (+Integer+, lambda, or +Proc+)
|
779
|
+
#
|
780
|
+
# === Returns
|
781
|
+
#
|
782
|
+
# Gcloud::Dns::Change
|
783
|
+
#
|
784
|
+
# === Example
|
785
|
+
#
|
786
|
+
# require "gcloud"
|
787
|
+
#
|
788
|
+
# gcloud = Gcloud.new
|
789
|
+
# dns = gcloud.dns
|
790
|
+
# zone = dns.zone "example-com"
|
791
|
+
# change = zone.modify "example.com.", "MX" do |mx|
|
792
|
+
# mx.ttl = 3600 # change only the TTL
|
793
|
+
# end
|
794
|
+
#
|
795
|
+
def modify name, type, options = {}
|
796
|
+
existing = records(name: name, type: type).all.to_a
|
797
|
+
updated = existing.map(&:dup)
|
798
|
+
updated.each { |r| yield r }
|
799
|
+
update updated, existing, options
|
800
|
+
end
|
801
|
+
|
802
|
+
##
|
803
|
+
# This helper converts the given domain name or subdomain (e.g., +www+)
|
804
|
+
# fragment to a {fully qualified domain name
|
805
|
+
# (FQDN)}[https://en.wikipedia.org/wiki/Fully_qualified_domain_name] for
|
806
|
+
# the zone's #dns. If the argument is already a FQDN, it is returned
|
807
|
+
# unchanged.
|
808
|
+
#
|
809
|
+
# === Parameters
|
810
|
+
#
|
811
|
+
# +domain_name+::
|
812
|
+
# The name to convert to a fully qualified domain name. (+String+)
|
813
|
+
#
|
814
|
+
# === Returns
|
815
|
+
#
|
816
|
+
# A fully qualified domain name. (+String+)
|
817
|
+
#
|
818
|
+
# === Examples
|
819
|
+
#
|
820
|
+
# require "gcloud"
|
821
|
+
#
|
822
|
+
# gcloud = Gcloud.new
|
823
|
+
# dns = gcloud.dns
|
824
|
+
# zone = dns.zone "example-com"
|
825
|
+
# zone.fqdn "www" #=> "www.example.com."
|
826
|
+
# zone.fqdn "@" #=> "example.com."
|
827
|
+
# zone.fqdn "mail.example.com." #=> "mail.example.com."
|
828
|
+
#
|
829
|
+
def fqdn domain_name
|
830
|
+
Connection.fqdn domain_name, dns
|
831
|
+
end
|
832
|
+
|
833
|
+
##
|
834
|
+
# New Zone from a Google API Client object.
|
835
|
+
def self.from_gapi gapi, conn #:nodoc:
|
836
|
+
new.tap do |f|
|
837
|
+
f.gapi = gapi
|
838
|
+
f.connection = conn
|
839
|
+
end
|
840
|
+
end
|
841
|
+
|
842
|
+
protected
|
843
|
+
|
844
|
+
##
|
845
|
+
# Raise an error unless an active connection is available.
|
846
|
+
def ensure_connection!
|
847
|
+
fail "Must have active connection" unless connection
|
848
|
+
end
|
849
|
+
|
850
|
+
# rubocop:disable all
|
851
|
+
# Disabled rubocop because this complexity cannot easily be avoided.
|
852
|
+
|
853
|
+
def build_records_options name, type, options
|
854
|
+
# Handle only sending in options
|
855
|
+
if name.is_a?(::Hash) && type.nil? && options.empty?
|
856
|
+
options = name
|
857
|
+
name = nil
|
858
|
+
elsif type.is_a?(::Hash) && options.empty?
|
859
|
+
options = type
|
860
|
+
type = nil
|
861
|
+
end
|
862
|
+
|
863
|
+
# Set parameters as options, params have priority
|
864
|
+
options[:name] = name || options[:name]
|
865
|
+
options[:type] = type || options[:type]
|
866
|
+
|
867
|
+
# Ensure name is a FQDN
|
868
|
+
options[:name] = fqdn(options[:name]) if options[:name]
|
869
|
+
|
870
|
+
# return only the options
|
871
|
+
options
|
872
|
+
end
|
873
|
+
|
874
|
+
# rubocop:enable all
|
875
|
+
|
876
|
+
def create_change additions, deletions
|
877
|
+
ensure_connection!
|
878
|
+
resp = connection.create_change id,
|
879
|
+
additions.map(&:to_gapi),
|
880
|
+
deletions.map(&:to_gapi)
|
881
|
+
if resp.success?
|
882
|
+
Change.from_gapi resp.data, self
|
883
|
+
else
|
884
|
+
fail ApiError.from_response(resp)
|
885
|
+
end
|
886
|
+
end
|
887
|
+
|
888
|
+
def increment_soa to_add, to_remove, soa_serial
|
889
|
+
current_soa = detect_soa records(name: dns, type: "SOA").all
|
890
|
+
return false if current_soa.nil?
|
891
|
+
updated_soa = current_soa.dup
|
892
|
+
updated_soa.data[0] = replace_soa_serial updated_soa.data[0], soa_serial
|
893
|
+
to_add << updated_soa
|
894
|
+
to_remove << current_soa
|
895
|
+
end
|
896
|
+
|
897
|
+
def detect_soa records
|
898
|
+
records.detect { |r| r.type == "SOA" }
|
899
|
+
end
|
900
|
+
|
901
|
+
def replace_soa_serial soa_data, soa_serial
|
902
|
+
soa_data = soa_data.split " "
|
903
|
+
current_serial = soa_data[2].to_i
|
904
|
+
soa_data[2] = if soa_serial && soa_serial.respond_to?(:call)
|
905
|
+
soa_serial.call current_serial
|
906
|
+
elsif soa_serial
|
907
|
+
soa_serial.to_i
|
908
|
+
else
|
909
|
+
current_serial + 1
|
910
|
+
end
|
911
|
+
soa_data.join " "
|
912
|
+
end
|
913
|
+
|
914
|
+
def adjust_change_sort_order order
|
915
|
+
return nil if order.nil?
|
916
|
+
if order.to_s.downcase.start_with? "d"
|
917
|
+
"descending"
|
918
|
+
else
|
919
|
+
"ascending"
|
920
|
+
end
|
921
|
+
end
|
922
|
+
end
|
923
|
+
end
|
924
|
+
end
|