dnsimple 2.0.0.a → 2.0.0.alpha2
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 +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +1 -2
- data/CHANGELOG.markdown +26 -2
- data/Gemfile +2 -0
- data/README.markdown +56 -36
- data/Rakefile +0 -1
- data/{dnsimple-ruby.gemspec → dnsimple.gemspec} +6 -4
- data/lib/dnsimple.rb +1 -1
- data/lib/dnsimple/base.rb +1 -1
- data/lib/dnsimple/certificate.rb +49 -35
- data/lib/dnsimple/client.rb +25 -72
- data/lib/dnsimple/contact.rb +12 -9
- data/lib/dnsimple/domain.rb +117 -82
- data/lib/dnsimple/error.rb +13 -2
- data/lib/dnsimple/extended_attribute.rb +3 -3
- data/lib/dnsimple/record.rb +9 -9
- data/lib/dnsimple/service.rb +3 -3
- data/lib/dnsimple/template.rb +8 -6
- data/lib/dnsimple/template_record.rb +8 -8
- data/lib/dnsimple/transfer_order.rb +2 -2
- data/lib/dnsimple/user.rb +26 -2
- data/lib/dnsimple/version.rb +2 -2
- data/spec/dnsimple/certificate_spec.rb +8 -5
- data/spec/dnsimple/client_spec.rb +56 -9
- data/spec/dnsimple/contact_spec.rb +2 -2
- data/spec/dnsimple/domain_spec.rb +140 -32
- data/spec/dnsimple/extended_attributes_spec.rb +1 -1
- data/spec/dnsimple/record_spec.rb +2 -2
- data/spec/dnsimple/template_spec.rb +1 -1
- data/spec/dnsimple/user_spec.rb +40 -1
- data/spec/files/2fa/error-badtoken.http +22 -0
- data/spec/files/2fa/error-required.http +23 -0
- data/spec/files/2fa/exchange-token.http +25 -0
- data/spec/files/account/user/success.http +3 -3
- data/spec/files/certificates/index/success.http +2 -2
- data/spec/files/certificates/show/notfound.http +2 -2
- data/spec/files/certificates/show/success.http +2 -2
- data/spec/files/contacts/show/notfound.http +2 -2
- data/spec/files/contacts/show/success.http +3 -3
- data/spec/files/domains/auto_renewal_disable/notfound.http +1 -1
- data/spec/files/domains/auto_renewal_disable/success.http +1 -1
- data/spec/files/domains/auto_renewal_enable/notfound.http +1 -1
- data/spec/files/domains/auto_renewal_enable/success.http +1 -1
- data/spec/files/domains/create/success.http +19 -0
- data/spec/files/domains/delete/success-204.http +18 -0
- data/spec/files/domains/delete/success.http +19 -0
- data/spec/files/domains/index/success.http +19 -0
- data/spec/files/domains/{show/notfound.http → notfound.http} +2 -2
- data/spec/files/domains/show/success.http +2 -2
- data/spec/files/extended_attributes/ca.http +2 -2
- data/spec/files/extended_attributes/com.http +2 -2
- data/spec/files/extended_attributes/success.http +2 -2
- data/spec/files/records/index/success.http +2 -2
- data/spec/files/records/show/notfound.http +2 -2
- data/spec/files/records/show/success.http +2 -2
- data/spec/files/templates/show/notfound.http +2 -2
- data/spec/files/templates/show/success.http +2 -2
- data/spec/spec_helper.rb +9 -9
- metadata +45 -33
- data/lib/dnsimple-ruby.rb +0 -1
- data/spec/ci/.dnsimple.test +0 -3
data/lib/dnsimple/contact.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Dnsimple
|
2
2
|
|
3
3
|
# Represents a contact.
|
4
4
|
class Contact < Base
|
@@ -68,7 +68,7 @@ module DNSimple
|
|
68
68
|
# pass "first" it will be resolved to "first_name", "email" is resolved
|
69
69
|
# to "email_address" and so on.
|
70
70
|
def self.resolve(name)
|
71
|
-
|
71
|
+
Contact::Aliases[name.to_s] || name
|
72
72
|
end
|
73
73
|
|
74
74
|
def self.resolve_attributes(attributes)
|
@@ -86,7 +86,7 @@ module DNSimple
|
|
86
86
|
contact_hash = resolve_attributes(attributes)
|
87
87
|
|
88
88
|
options.merge!({:body => {:contact => contact_hash}})
|
89
|
-
response =
|
89
|
+
response = Client.post("/v1/contacts", options)
|
90
90
|
|
91
91
|
case response.code
|
92
92
|
when 201
|
@@ -97,7 +97,7 @@ module DNSimple
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def self.find(id, options={})
|
100
|
-
response =
|
100
|
+
response = Client.get("/v1/contacts/#{id}", options)
|
101
101
|
|
102
102
|
case response.code
|
103
103
|
when 200
|
@@ -110,7 +110,7 @@ module DNSimple
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def self.all(options={})
|
113
|
-
response =
|
113
|
+
response = Client.get("/v1/contacts", options)
|
114
114
|
|
115
115
|
case response.code
|
116
116
|
when 200
|
@@ -129,12 +129,12 @@ module DNSimple
|
|
129
129
|
contact_hash = {}
|
130
130
|
%w(first_name last_name organization_name job_title address1 address2 city
|
131
131
|
state_province postal_code country email_address phone phone_ext fax).each do |attribute|
|
132
|
-
contact_hash[
|
132
|
+
contact_hash[Contact.resolve(attribute)] = self.send(attribute)
|
133
133
|
end
|
134
134
|
|
135
135
|
options.merge!({:body => {:contact => contact_hash}})
|
136
136
|
|
137
|
-
response =
|
137
|
+
response = Client.put("/v1/contacts/#{id}", options)
|
138
138
|
|
139
139
|
case response.code
|
140
140
|
when 200
|
@@ -144,9 +144,12 @@ module DNSimple
|
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
147
|
-
#
|
147
|
+
# #delete the contact from DNSimple.
|
148
|
+
#
|
149
|
+
# WARNING: this cannot be undone.
|
150
|
+
#
|
148
151
|
def delete(options={})
|
149
|
-
|
152
|
+
Client.delete("/v1/contacts/#{id}", options)
|
150
153
|
end
|
151
154
|
alias :destroy :delete
|
152
155
|
|
data/lib/dnsimple/domain.rb
CHANGED
@@ -1,64 +1,66 @@
|
|
1
|
-
module
|
1
|
+
module Dnsimple
|
2
2
|
class Domain < Base
|
3
3
|
|
4
|
-
# The domain ID in DNSimple
|
4
|
+
# The Fixnum domain ID in DNSimple.
|
5
5
|
attr_accessor :id
|
6
6
|
|
7
|
-
# The
|
8
|
-
attr_accessor :
|
9
|
-
|
10
|
-
# When the domain was created in DNSimple
|
11
|
-
attr_accessor :created_at
|
12
|
-
|
13
|
-
# When the domain was last update in DNSimple
|
14
|
-
attr_accessor :updated_at
|
7
|
+
# The Fixnum associated user ID.
|
8
|
+
attr_accessor :user_id
|
15
9
|
|
16
|
-
# The
|
17
|
-
attr_accessor :
|
10
|
+
# The Fixnum associated registrant ID.
|
11
|
+
attr_accessor :registrant_id
|
18
12
|
|
19
|
-
#
|
20
|
-
attr_accessor :
|
13
|
+
# The String name.
|
14
|
+
attr_accessor :name
|
21
15
|
|
22
|
-
# The state
|
16
|
+
# The String state.
|
23
17
|
attr_accessor :state
|
24
18
|
|
25
|
-
#
|
26
|
-
attr_accessor :
|
19
|
+
# The String API token
|
20
|
+
attr_accessor :token
|
27
21
|
|
28
|
-
#
|
29
|
-
attr_accessor :user_id
|
30
|
-
|
31
|
-
# Is the domain lockable
|
32
|
-
attr_accessor :lockable
|
33
|
-
|
34
|
-
# Is the domain set to autorenew
|
22
|
+
# Is the domain set to auto renew?
|
35
23
|
attr_accessor :auto_renew
|
36
|
-
|
37
|
-
# Is the whois information protected
|
24
|
+
|
25
|
+
# Is the whois information protected?
|
38
26
|
attr_accessor :whois_protected
|
39
27
|
|
28
|
+
# The Date the domain will expire.
|
29
|
+
attr_accessor :expires_on
|
40
30
|
|
41
|
-
#
|
42
|
-
|
43
|
-
|
31
|
+
# The Date the domain was created in DNSimple.
|
32
|
+
attr_accessor :created_at
|
33
|
+
|
34
|
+
# The Date the domain was last update in DNSimple.
|
35
|
+
attr_accessor :updated_at
|
36
|
+
|
37
|
+
|
38
|
+
# Lists the domains in the DNSimple account.
|
39
|
+
#
|
40
|
+
# @return [Array<Domain>]
|
41
|
+
def self.list(options = {})
|
42
|
+
response = Client.get("/v1/domains", options)
|
44
43
|
|
45
44
|
case response.code
|
46
45
|
when 200
|
47
|
-
"
|
48
|
-
when 404
|
49
|
-
"available"
|
46
|
+
response.map { |r| new(r["domain"]) }
|
50
47
|
else
|
51
|
-
raise RequestError.new("Error
|
48
|
+
raise RequestError.new("Error listing domains", response)
|
52
49
|
end
|
53
50
|
end
|
54
51
|
|
55
|
-
|
56
|
-
# method returns a Domain instance if the name is created
|
57
|
-
# and raises an error otherwise.
|
58
|
-
def self.create(name, options={})
|
59
|
-
options.merge!({:body => {:domain => {:name => name}}})
|
52
|
+
def self.all(*args); list(*args); end
|
60
53
|
|
61
|
-
|
54
|
+
# Creates the domain in the DNSimple account.
|
55
|
+
#
|
56
|
+
# @param [String] name The domain name.
|
57
|
+
#
|
58
|
+
# @return [Domain] The newly created domain.
|
59
|
+
# @raise [RequestError] When the request fails.
|
60
|
+
def self.create(name)
|
61
|
+
options = { body: { domain: { name: name }}}
|
62
|
+
|
63
|
+
response = Client.post("/v1/domains", options)
|
62
64
|
|
63
65
|
case response.code
|
64
66
|
when 201
|
@@ -68,6 +70,62 @@ module DNSimple
|
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
73
|
+
# Gets a specific domain in the account.
|
74
|
+
#
|
75
|
+
# @param [Fixnum,String] id Either the numeric ID or the fully-qualified domain name.
|
76
|
+
#
|
77
|
+
# @return [Domain] The domain.
|
78
|
+
# @raise [RecordNotFound] When the domain doesn't exist.
|
79
|
+
# @raise [RequestError] When the request fails.
|
80
|
+
def self.find(id)
|
81
|
+
response = Client.get("/v1/domains/#{id}")
|
82
|
+
|
83
|
+
case response.code
|
84
|
+
when 200
|
85
|
+
new(response["domain"])
|
86
|
+
when 404
|
87
|
+
raise RecordNotFound, "Could not find domain #{id}"
|
88
|
+
else
|
89
|
+
raise RequestError.new("Error finding domain", response)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Deletes a specific domain from the account.
|
94
|
+
#
|
95
|
+
# WARNING: this cannot be undone.
|
96
|
+
#
|
97
|
+
# @param [Fixnum,String] id Either the numeric ID or the fully-qualified domain name.
|
98
|
+
#
|
99
|
+
# @return [void]
|
100
|
+
# @raise [RecordNotFound] When the domain doesn't exist.
|
101
|
+
# @raise [RequestError] When the request fails.
|
102
|
+
def self.delete(id)
|
103
|
+
response = Client.delete("/v1/domains/#{id}")
|
104
|
+
|
105
|
+
case response.code
|
106
|
+
when 200, 204
|
107
|
+
true
|
108
|
+
when 404
|
109
|
+
raise RecordNotFound, "Could not find domain #{id}"
|
110
|
+
else
|
111
|
+
raise RequestError.new("Error deleting domain", response)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Check the availability of a name
|
116
|
+
def self.check(name, options={})
|
117
|
+
response = Client.get("/v1/domains/#{name}/check", options)
|
118
|
+
|
119
|
+
case response.code
|
120
|
+
when 200
|
121
|
+
"registered"
|
122
|
+
when 404
|
123
|
+
"available"
|
124
|
+
else
|
125
|
+
raise RequestError.new("Error checking availability", response)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
71
129
|
# Purchase a domain name.
|
72
130
|
def self.register(name, registrant={}, extended_attributes={}, options={})
|
73
131
|
body = {:domain => {:name => name}}
|
@@ -75,48 +133,22 @@ module DNSimple
|
|
75
133
|
if registrant[:id]
|
76
134
|
body[:domain][:registrant_id] = registrant[:id]
|
77
135
|
else
|
78
|
-
body.merge!(:contact =>
|
136
|
+
body.merge!(:contact => Contact.resolve_attributes(registrant))
|
79
137
|
end
|
80
138
|
end
|
81
139
|
body.merge!(:extended_attribute => extended_attributes)
|
82
140
|
options.merge!({:body => body})
|
83
141
|
|
84
|
-
response =
|
142
|
+
response = Client.post("/v1/domain_registrations", options)
|
85
143
|
|
86
144
|
case response.code
|
87
145
|
when 201
|
88
|
-
return
|
146
|
+
return Domain.new(response["domain"])
|
89
147
|
else
|
90
148
|
raise RequestError.new("Error registering domain", response)
|
91
149
|
end
|
92
150
|
end
|
93
151
|
|
94
|
-
# Find a specific domain in the account either by the numeric ID
|
95
|
-
# or by the fully-qualified domain name.
|
96
|
-
def self.find(id, options={})
|
97
|
-
response = DNSimple::Client.get("/v1/domains/#{id}", options)
|
98
|
-
|
99
|
-
case response.code
|
100
|
-
when 200
|
101
|
-
new(response["domain"])
|
102
|
-
when 404
|
103
|
-
raise RecordNotFound, "Could not find domain #{id}"
|
104
|
-
else
|
105
|
-
raise RequestError.new("Error finding domain", response)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Get all domains for the account.
|
110
|
-
def self.all(options={})
|
111
|
-
response = DNSimple::Client.get("/v1/domains", options)
|
112
|
-
|
113
|
-
case response.code
|
114
|
-
when 200
|
115
|
-
response.map { |r| new(r["domain"]) }
|
116
|
-
else
|
117
|
-
raise RequestError.new("Error listing domains", response)
|
118
|
-
end
|
119
|
-
end
|
120
152
|
|
121
153
|
# Enable auto_renew on the domain
|
122
154
|
def enable_auto_renew
|
@@ -130,10 +162,13 @@ module DNSimple
|
|
130
162
|
auto_renew!(:delete)
|
131
163
|
end
|
132
164
|
|
133
|
-
#
|
134
|
-
#
|
135
|
-
|
136
|
-
|
165
|
+
# Deletes this domain from the account.
|
166
|
+
#
|
167
|
+
# WARNING: this cannot be undone.
|
168
|
+
#
|
169
|
+
# @see .delete
|
170
|
+
def delete
|
171
|
+
self.class.delete(name)
|
137
172
|
end
|
138
173
|
alias :destroy :delete
|
139
174
|
|
@@ -143,35 +178,35 @@ module DNSimple
|
|
143
178
|
options.merge!(:body => {})
|
144
179
|
template = resolve_template(template)
|
145
180
|
|
146
|
-
|
181
|
+
Client.post("/v1/domains/#{name}/templates/#{template.id}/apply", options)
|
147
182
|
end
|
148
183
|
|
149
184
|
def resolve_template(template)
|
150
185
|
case template
|
151
|
-
when
|
186
|
+
when Template
|
152
187
|
template
|
153
188
|
else
|
154
|
-
|
189
|
+
Template.find(template)
|
155
190
|
end
|
156
191
|
end
|
157
192
|
|
158
193
|
def applied_services(options={})
|
159
|
-
response =
|
194
|
+
response = Client.get("/v1/domains/#{name}/applied_services", options)
|
160
195
|
|
161
196
|
case response.code
|
162
197
|
when 200
|
163
|
-
response.map { |r|
|
198
|
+
response.map { |r| Service.new(r["service"]) }
|
164
199
|
else
|
165
200
|
raise RequestError.new("Error listing applied services", response)
|
166
201
|
end
|
167
202
|
end
|
168
203
|
|
169
204
|
def available_services(options={})
|
170
|
-
response =
|
205
|
+
response = Client.get("/v1/domains/#{name}/available_services", options)
|
171
206
|
|
172
207
|
case response.code
|
173
208
|
when 200
|
174
|
-
response.map { |r|
|
209
|
+
response.map { |r| Service.new(r["service"]) }
|
175
210
|
else
|
176
211
|
raise RequestError.new("Error listing available services", response)
|
177
212
|
end
|
@@ -179,7 +214,7 @@ module DNSimple
|
|
179
214
|
|
180
215
|
def add_service(id_or_short_name, options={})
|
181
216
|
options.merge!(:body => {:service => {:id => id_or_short_name}})
|
182
|
-
response =
|
217
|
+
response = Client.post("/v1/domains/#{name}/applied_services", options)
|
183
218
|
|
184
219
|
case response.code
|
185
220
|
when 200
|
@@ -190,7 +225,7 @@ module DNSimple
|
|
190
225
|
end
|
191
226
|
|
192
227
|
def remove_service(id, options={})
|
193
|
-
response =
|
228
|
+
response = Client.delete("/v1/domains/#{name}/applied_services/#{id}", options)
|
194
229
|
|
195
230
|
case response.code
|
196
231
|
when 200
|
@@ -204,7 +239,7 @@ module DNSimple
|
|
204
239
|
private
|
205
240
|
|
206
241
|
def auto_renew!(method)
|
207
|
-
response =
|
242
|
+
response = Client.send(method, "/v1/domains/#{name}/auto_renewal")
|
208
243
|
case response.code
|
209
244
|
when 200
|
210
245
|
self.auto_renew = response['domain']['auto_renew']
|
data/lib/dnsimple/error.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Dnsimple
|
2
2
|
|
3
3
|
class Error < StandardError
|
4
4
|
end
|
@@ -9,13 +9,24 @@ module DNSimple
|
|
9
9
|
class RecordNotFound < Error
|
10
10
|
end
|
11
11
|
|
12
|
+
# An exception that is raised if a method is called with missing or invalid parameter values.
|
13
|
+
class ValidationError < Error
|
14
|
+
end
|
15
|
+
|
12
16
|
class RequestError < Error
|
13
17
|
def initialize(description, response)
|
14
18
|
super("#{description}: #{response["error"]}")
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
18
|
-
class
|
22
|
+
class AuthenticationError < Error
|
23
|
+
end
|
24
|
+
|
25
|
+
class AuthenticationFailed < AuthenticationError
|
26
|
+
end
|
27
|
+
|
28
|
+
# An exception that is raised if a request is executed for an account that requires two-factor authentication.
|
29
|
+
class TwoFactorAuthenticationRequired < AuthenticationError
|
19
30
|
end
|
20
31
|
|
21
32
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Dnsimple
|
2
2
|
|
3
3
|
# Used for domains that require extended attributes.
|
4
4
|
class ExtendedAttribute < Base
|
@@ -32,13 +32,13 @@ module DNSimple
|
|
32
32
|
def options=(opts)
|
33
33
|
@options = []
|
34
34
|
opts.each do |opt|
|
35
|
-
@options <<
|
35
|
+
@options << ExtendedAttribute::Option.new(opt)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
# Find the extended attributes for the given TLD
|
40
40
|
def self.find(tld, options={})
|
41
|
-
response =
|
41
|
+
response = Client.get("/v1/extended_attributes/#{tld}", options)
|
42
42
|
|
43
43
|
case response.code
|
44
44
|
when 200
|
data/lib/dnsimple/record.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Dnsimple
|
2
2
|
|
3
3
|
class Record < Base
|
4
4
|
Aliases = {
|
@@ -16,18 +16,18 @@ module DNSimple
|
|
16
16
|
|
17
17
|
|
18
18
|
def fqdn
|
19
|
-
[name, domain.name].delete_if { |v| v !~
|
19
|
+
[name, domain.name].delete_if { |v| v !~ BLANK_REGEX }.join(".")
|
20
20
|
end
|
21
21
|
|
22
22
|
def save(options={})
|
23
23
|
record_hash = {}
|
24
24
|
%w(name content ttl prio).each do |attribute|
|
25
|
-
record_hash[
|
25
|
+
record_hash[Record.resolve(attribute)] = self.send(attribute)
|
26
26
|
end
|
27
27
|
|
28
28
|
options.merge!(:body => {:record => record_hash})
|
29
29
|
|
30
|
-
response =
|
30
|
+
response = Client.put("/v1/domains/#{domain.id}/records/#{id}", options)
|
31
31
|
|
32
32
|
case response.code
|
33
33
|
when 200
|
@@ -38,12 +38,12 @@ module DNSimple
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def delete(options={})
|
41
|
-
|
41
|
+
Client.delete("/v1/domains/#{domain.id}/records/#{id}", options)
|
42
42
|
end
|
43
43
|
alias :destroy :delete
|
44
44
|
|
45
45
|
def self.resolve(name)
|
46
|
-
|
46
|
+
Record::Aliases[name] || name
|
47
47
|
end
|
48
48
|
|
49
49
|
def self.create(domain, name, record_type, content, options={})
|
@@ -54,7 +54,7 @@ module DNSimple
|
|
54
54
|
|
55
55
|
options.merge!({:body => {:record => record_hash}})
|
56
56
|
|
57
|
-
response =
|
57
|
+
response = Client.post("/v1/domains/#{domain.name}/records", options)
|
58
58
|
|
59
59
|
case response.code
|
60
60
|
when 201
|
@@ -67,7 +67,7 @@ module DNSimple
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def self.find(domain, id, options={})
|
70
|
-
response =
|
70
|
+
response = Client.get("/v1/domains/#{domain.name}/records/#{id}", options)
|
71
71
|
|
72
72
|
case response.code
|
73
73
|
when 200
|
@@ -80,7 +80,7 @@ module DNSimple
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def self.all(domain, options={})
|
83
|
-
response =
|
83
|
+
response = Client.get("/v1/domains/#{domain.name}/records", options)
|
84
84
|
|
85
85
|
case response.code
|
86
86
|
when 200
|