google-cloud-dns 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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