google-cloud-dns 0.20.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.
@@ -0,0 +1,173 @@
1
+ # Copyright 2015 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/dns/record/list"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Dns
21
+ ##
22
+ # # DNS Record
23
+ #
24
+ # Represents a set of DNS resource records (RRs) for a given
25
+ # {Google::Cloud::Dns::Record#name} and {Google::Cloud::Dns::Record#type}
26
+ # in a {Google::Cloud::Dns::Zone}. Since it is a value object, a newly
27
+ # created Record instance is transient until it is added to a Zone with
28
+ # {Google::Cloud::Dns::Zone#update}. Note that
29
+ # {Google::Cloud::Dns::Zone#add} and the {Google::Cloud::Dns::Zone#update}
30
+ # block parameter can be used instead of {Google::Cloud::Dns::Zone#record}
31
+ # or `Record.new` to create new records.
32
+ #
33
+ # @example
34
+ # require "google/cloud"
35
+ #
36
+ # gcloud = Google::Cloud.new
37
+ # dns = gcloud.dns
38
+ # zone = dns.zone "example-com"
39
+ #
40
+ # zone.records.count #=> 2
41
+ # record = zone.record "example.com.", "A", 86400, "1.2.3.4"
42
+ # zone.records.count #=> 2
43
+ # change = zone.update record
44
+ # zone.records.count #=> 3
45
+ #
46
+ class Record
47
+ ##
48
+ # The owner of the record. For example: `example.com.`.
49
+ #
50
+ # @return [String]
51
+ #
52
+ attr_accessor :name
53
+
54
+ ##
55
+ # The identifier of a [supported record type
56
+ # ](https://cloud.google.com/dns/what-is-cloud-dns#supported_record_types).
57
+ # For example: `A`, `AAAA`, `CNAME`, `MX`, or `TXT`.
58
+ #
59
+ # @return [String]
60
+ #
61
+ attr_accessor :type
62
+
63
+ ##
64
+ # The number of seconds that the record can be cached by resolvers.
65
+ #
66
+ # @return [Integer]
67
+ #
68
+ attr_accessor :ttl
69
+
70
+ ##
71
+ # The array of resource record data, as determined by `type` and defined
72
+ # in [RFC 1035 (section
73
+ # 5)](http://tools.ietf.org/html/rfc1035#section-5) and [RFC 1034
74
+ # (section 3.6.1)](http://tools.ietf.org/html/rfc1034#section-3.6.1).
75
+ # For example: ["10 mail.example.com.", "20 mail2.example.com."].
76
+ #
77
+ # @return [Array<String>]
78
+ #
79
+ attr_accessor :data
80
+
81
+ ##
82
+ # Creates a Record value object.
83
+ #
84
+ # @param [String] name The owner of the record. For example:
85
+ # `example.com.`.
86
+ # @param [String] type The identifier of a [supported record
87
+ # type](https://cloud.google.com/dns/what-is-cloud-dns).
88
+ # For example: `A`, `AAAA`, `CNAME`, `MX`, or `TXT`.
89
+ # @param [Integer] ttl The number of seconds that the record can be
90
+ # cached by resolvers.
91
+ # @param [String, Array<String>] data The resource record data, as
92
+ # determined by `type` and defined in [RFC
93
+ # 1035 (section 5)](http://tools.ietf.org/html/rfc1035#section-5) and
94
+ # [RFC 1034
95
+ # (section 3.6.1)](http://tools.ietf.org/html/rfc1034#section-3.6.1).
96
+ # For example: ["10 mail.example.com.", "20 mail2.example.com."].
97
+ #
98
+ def initialize name, type, ttl, data
99
+ fail ArgumentError, "name is required" unless name
100
+ fail ArgumentError, "type is required" unless type
101
+ fail ArgumentError, "ttl is required" unless ttl
102
+ fail ArgumentError, "data is required" unless data
103
+ @name = name.to_s
104
+ @type = type.to_s.upcase
105
+ @ttl = Integer(ttl)
106
+ @data = Array(data)
107
+ end
108
+
109
+ ##
110
+ # @private Returns an array of strings in the zone file format, one
111
+ # for each element in the record's data array.
112
+ def to_zonefile_records
113
+ data.map do |rrdata|
114
+ "#{name} #{ttl} IN #{type} #{rrdata}"
115
+ end
116
+ end
117
+
118
+ ##
119
+ # Returns a deep copy of the record. Useful for updating records, since
120
+ # the original, unmodified record must be passed for deletion when using
121
+ # {Google::Cloud::Dns::Zone#update}.
122
+ #
123
+ def dup
124
+ other = super
125
+ other.data = data.map(&:dup)
126
+ other
127
+ end
128
+
129
+ ##
130
+ # @private New Record from a Google API Client object.
131
+ def self.from_gapi gapi
132
+ new gapi.name, gapi.type, gapi.ttl, gapi.rrdatas
133
+ end
134
+
135
+ ##
136
+ # @private Convert the record object to a Google API hash.
137
+ def to_gapi
138
+ Google::Apis::DnsV1::ResourceRecordSet.new(
139
+ kind: "dns#resourceRecordSet",
140
+ name: name,
141
+ rrdatas: data,
142
+ ttl: ttl,
143
+ type: type
144
+ )
145
+ end
146
+
147
+ # @private
148
+ def hash
149
+ [name, type, ttl, data].hash
150
+ end
151
+
152
+ # @private
153
+ def eql? other
154
+ return false unless other.is_a? self.class
155
+ name == other.name && type == other.type &&
156
+ ttl == other.ttl && data == other.data
157
+ end
158
+
159
+ # @private
160
+ def == other
161
+ self.eql? other
162
+ end
163
+
164
+ # @private
165
+ def <=> other
166
+ return nil unless other.is_a? self.class
167
+ [name, type, ttl, data] <=>
168
+ [other.name, other.type, other.ttl, other.data]
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,177 @@
1
+ # Copyright 2015 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "delegate"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Dns
21
+ class Record
22
+ ##
23
+ # Record::List is a special case Array with additional values.
24
+ class List < DelegateClass(::Array)
25
+ ##
26
+ # If not empty, indicates that there are more records that match
27
+ # the request and this value should be passed to continue.
28
+ attr_accessor :token
29
+
30
+ ##
31
+ # @private Create a new Record::List with an array of Record
32
+ # instances.
33
+ def initialize arr = []
34
+ super arr
35
+ end
36
+
37
+ ##
38
+ # Whether there a next page of records.
39
+ #
40
+ # @return [Boolean]
41
+ #
42
+ # @example
43
+ # require "google/cloud"
44
+ #
45
+ # gcloud = Google::Cloud.new
46
+ # dns = gcloud.dns
47
+ # zone = dns.zone "example-com"
48
+ #
49
+ # records = zone.records "example.com."
50
+ # if records.next?
51
+ # next_records = records.next
52
+ # end
53
+ #
54
+ def next?
55
+ !token.nil?
56
+ end
57
+
58
+ ##
59
+ # Retrieve the next page of records.
60
+ #
61
+ # @return [Record::List]
62
+ #
63
+ # @example
64
+ # require "google/cloud"
65
+ #
66
+ # gcloud = Google::Cloud.new
67
+ # dns = gcloud.dns
68
+ # zone = dns.zone "example-com"
69
+ #
70
+ # records = zone.records "example.com."
71
+ # if records.next?
72
+ # next_records = records.next
73
+ # end
74
+ #
75
+ def next
76
+ return nil unless next?
77
+ ensure_zone!
78
+ @zone.records @name, @type, token: token, max: @max
79
+ end
80
+
81
+ ##
82
+ # Retrieves all records by repeatedly loading {#next} until {#next?}
83
+ # returns `false`. Calls the given block once for each record, which
84
+ # is passed as the parameter.
85
+ #
86
+ # An Enumerator is returned if no block is given.
87
+ #
88
+ # This method may make several API calls until all records are
89
+ # retrieved. Be sure to use as narrow a search criteria as possible.
90
+ # Please use with caution.
91
+ #
92
+ # @param [Integer] request_limit The upper limit of API requests to
93
+ # make to load all records. Default is no limit.
94
+ # @yield [record] The block for accessing each record.
95
+ # @yieldparam [Record] record The record object.
96
+ #
97
+ # @return [Enumerator]
98
+ #
99
+ # @example Iterating each record by passing a block:
100
+ # require "google/cloud"
101
+ #
102
+ # gcloud = Google::Cloud.new
103
+ # dns = gcloud.dns
104
+ # zone = dns.zone "example-com"
105
+ # records = zone.records "example.com."
106
+ #
107
+ # records.all do |record|
108
+ # puts record.name
109
+ # end
110
+ #
111
+ # @example Using the enumerator by not passing a block:
112
+ # require "google/cloud"
113
+ #
114
+ # gcloud = Google::Cloud.new
115
+ # dns = gcloud.dns
116
+ # zone = dns.zone "example-com"
117
+ # records = zone.records "example.com."
118
+ #
119
+ # all_names = records.all.map do |record|
120
+ # record.name
121
+ # end
122
+ #
123
+ # @example Limit the number of API calls made:
124
+ # require "google/cloud"
125
+ #
126
+ # gcloud = Google::Cloud.new
127
+ # dns = gcloud.dns
128
+ # zone = dns.zone "example-com"
129
+ # records = zone.records "example.com."
130
+ #
131
+ # records.all(request_limit: 10) do |record|
132
+ # puts record.name
133
+ # end
134
+ #
135
+ def all request_limit: nil
136
+ request_limit = request_limit.to_i if request_limit
137
+ unless block_given?
138
+ return enum_for(:all, request_limit: request_limit)
139
+ end
140
+ results = self
141
+ loop do
142
+ results.each { |r| yield r }
143
+ if request_limit
144
+ request_limit -= 1
145
+ break if request_limit < 0
146
+ end
147
+ break unless results.next?
148
+ results = results.next
149
+ end
150
+ end
151
+
152
+ ##
153
+ # @private New Records::List from a response object.
154
+ def self.from_gapi gapi, zone, name = nil, type = nil, max = nil
155
+ records = new(Array(gapi.rrsets).map do |g|
156
+ Record.from_gapi g
157
+ end)
158
+ records.instance_variable_set "@token", gapi.next_page_token
159
+ records.instance_variable_set "@zone", zone
160
+ records.instance_variable_set "@name", name
161
+ records.instance_variable_set "@type", type
162
+ records.instance_variable_set "@max", max
163
+ records
164
+ end
165
+
166
+ protected
167
+
168
+ ##
169
+ # Raise an error unless an active connection is available.
170
+ def ensure_zone!
171
+ fail "Must have active connection" unless @zone
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,166 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/errors"
17
+ require "google/cloud/dns/version"
18
+ require "google/apis/dns_v1"
19
+
20
+ module Google
21
+ module Cloud
22
+ module Dns
23
+ ##
24
+ # @private
25
+ # Represents the service to DNS, exposing the API calls.
26
+ class Service
27
+ ##
28
+ # Alias to the Google Client API module
29
+ API = Google::Apis::DnsV1
30
+
31
+ attr_accessor :project
32
+ attr_accessor :credentials
33
+
34
+ ##
35
+ # Creates a new Service instance.
36
+ def initialize project, credentials, retries: nil, timeout: nil
37
+ @project = project
38
+ @credentials = credentials
39
+ @service = API::DnsService.new
40
+ @service.client_options.application_name = "google-cloud-dns"
41
+ @service.client_options.application_version = \
42
+ Google::Cloud::Dns::VERSION
43
+ @service.request_options.retries = retries || 3
44
+ @service.request_options.timeout_sec = timeout if timeout
45
+ @service.authorization = @credentials.client
46
+ end
47
+
48
+ def service
49
+ return mocked_service if mocked_service
50
+ @service
51
+ end
52
+ attr_accessor :mocked_service
53
+
54
+ ##
55
+ # Returns Google::Apis::DnsV1::Project
56
+ def get_project project_id = @project
57
+ execute { service.get_project project_id }
58
+ end
59
+
60
+ ##
61
+ # Returns Google::Apis::DnsV1::ManagedZone
62
+ def get_zone zone_id
63
+ execute { service.get_managed_zone @project, zone_id }
64
+ end
65
+
66
+ ##
67
+ # Returns Google::Apis::DnsV1::ListManagedZonesResponse
68
+ def list_zones token: nil, max: nil
69
+ execute do
70
+ service.list_managed_zones @project, max_results: max,
71
+ page_token: token
72
+ end
73
+ end
74
+
75
+ ##
76
+ # Returns Google::Apis::DnsV1::ManagedZone
77
+ def create_zone zone_name, zone_dns, description: nil,
78
+ name_server_set: nil
79
+ managed_zone = Google::Apis::DnsV1::ManagedZone.new(
80
+ kind: "dns#managedZone",
81
+ name: zone_name,
82
+ dns_name: zone_dns,
83
+ description: (description || ""),
84
+ name_server_set: name_server_set
85
+ )
86
+ execute { service.create_managed_zone @project, managed_zone }
87
+ end
88
+
89
+ def delete_zone zone_id
90
+ execute { service.delete_managed_zone @project, zone_id }
91
+ end
92
+
93
+ ##
94
+ # Returns Google::Apis::DnsV1::Change
95
+ def get_change zone_id, change_id
96
+ execute { service.get_change @project, zone_id, change_id }
97
+ end
98
+
99
+ ##
100
+ # Returns Google::Apis::DnsV1::ListChangesResponse
101
+ def list_changes zone_id, token: nil, max: nil, order: nil, sort: nil
102
+ execute do
103
+ service.list_changes @project, zone_id, max_results: max,
104
+ page_token: token,
105
+ sort_by: sort,
106
+ sort_order: order
107
+ end
108
+ end
109
+
110
+ ##
111
+ # Returns Google::Apis::DnsV1::Change
112
+ def create_change zone_id, additions, deletions
113
+ change = Google::Apis::DnsV1::Change.new(
114
+ kind: "dns#change",
115
+ additions: Array(additions),
116
+ deletions: Array(deletions)
117
+ )
118
+ execute { service.create_change @project, zone_id, change }
119
+ end
120
+
121
+ ##
122
+ # Returns Google::Apis::DnsV1::ListResourceRecordSetsResponse
123
+ def list_records zone_id, name = nil, type = nil, token: nil, max: nil
124
+ execute do
125
+ service.list_resource_record_sets @project, zone_id,
126
+ max_results: max, name: name,
127
+ page_token: token, type: type
128
+ end
129
+ end
130
+
131
+ ##
132
+ # Fully Qualified Domain Name
133
+ def self.fqdn name, origin_dns
134
+ name = name.to_s.strip
135
+ return name if self.ip_addr? name
136
+ name = origin_dns if name.empty?
137
+ name = origin_dns if name == "@"
138
+ name = "#{name}.#{origin_dns}" unless name.include? "."
139
+ name = "#{name}." unless name.end_with? "."
140
+ name
141
+ end
142
+
143
+ require "ipaddr"
144
+
145
+ def self.ip_addr? name
146
+ IPAddr.new name
147
+ true
148
+ rescue IPAddr::Error
149
+ false
150
+ end
151
+
152
+ def inspect
153
+ "#{self.class}(#{@project})"
154
+ end
155
+
156
+ protected
157
+
158
+ def execute
159
+ yield
160
+ rescue Google::Apis::Error => e
161
+ raise Google::Cloud::Error.from_error(e)
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end