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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +1 -2
  5. data/CHANGELOG.markdown +26 -2
  6. data/Gemfile +2 -0
  7. data/README.markdown +56 -36
  8. data/Rakefile +0 -1
  9. data/{dnsimple-ruby.gemspec → dnsimple.gemspec} +6 -4
  10. data/lib/dnsimple.rb +1 -1
  11. data/lib/dnsimple/base.rb +1 -1
  12. data/lib/dnsimple/certificate.rb +49 -35
  13. data/lib/dnsimple/client.rb +25 -72
  14. data/lib/dnsimple/contact.rb +12 -9
  15. data/lib/dnsimple/domain.rb +117 -82
  16. data/lib/dnsimple/error.rb +13 -2
  17. data/lib/dnsimple/extended_attribute.rb +3 -3
  18. data/lib/dnsimple/record.rb +9 -9
  19. data/lib/dnsimple/service.rb +3 -3
  20. data/lib/dnsimple/template.rb +8 -6
  21. data/lib/dnsimple/template_record.rb +8 -8
  22. data/lib/dnsimple/transfer_order.rb +2 -2
  23. data/lib/dnsimple/user.rb +26 -2
  24. data/lib/dnsimple/version.rb +2 -2
  25. data/spec/dnsimple/certificate_spec.rb +8 -5
  26. data/spec/dnsimple/client_spec.rb +56 -9
  27. data/spec/dnsimple/contact_spec.rb +2 -2
  28. data/spec/dnsimple/domain_spec.rb +140 -32
  29. data/spec/dnsimple/extended_attributes_spec.rb +1 -1
  30. data/spec/dnsimple/record_spec.rb +2 -2
  31. data/spec/dnsimple/template_spec.rb +1 -1
  32. data/spec/dnsimple/user_spec.rb +40 -1
  33. data/spec/files/2fa/error-badtoken.http +22 -0
  34. data/spec/files/2fa/error-required.http +23 -0
  35. data/spec/files/2fa/exchange-token.http +25 -0
  36. data/spec/files/account/user/success.http +3 -3
  37. data/spec/files/certificates/index/success.http +2 -2
  38. data/spec/files/certificates/show/notfound.http +2 -2
  39. data/spec/files/certificates/show/success.http +2 -2
  40. data/spec/files/contacts/show/notfound.http +2 -2
  41. data/spec/files/contacts/show/success.http +3 -3
  42. data/spec/files/domains/auto_renewal_disable/notfound.http +1 -1
  43. data/spec/files/domains/auto_renewal_disable/success.http +1 -1
  44. data/spec/files/domains/auto_renewal_enable/notfound.http +1 -1
  45. data/spec/files/domains/auto_renewal_enable/success.http +1 -1
  46. data/spec/files/domains/create/success.http +19 -0
  47. data/spec/files/domains/delete/success-204.http +18 -0
  48. data/spec/files/domains/delete/success.http +19 -0
  49. data/spec/files/domains/index/success.http +19 -0
  50. data/spec/files/domains/{show/notfound.http → notfound.http} +2 -2
  51. data/spec/files/domains/show/success.http +2 -2
  52. data/spec/files/extended_attributes/ca.http +2 -2
  53. data/spec/files/extended_attributes/com.http +2 -2
  54. data/spec/files/extended_attributes/success.http +2 -2
  55. data/spec/files/records/index/success.http +2 -2
  56. data/spec/files/records/show/notfound.http +2 -2
  57. data/spec/files/records/show/success.http +2 -2
  58. data/spec/files/templates/show/notfound.http +2 -2
  59. data/spec/files/templates/show/success.http +2 -2
  60. data/spec/spec_helper.rb +9 -9
  61. metadata +45 -33
  62. data/lib/dnsimple-ruby.rb +0 -1
  63. data/spec/ci/.dnsimple.test +0 -3
@@ -1,4 +1,4 @@
1
- module DNSimple
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
- DNSimple::Contact::Aliases[name.to_s] || name
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 = DNSimple::Client.post("/v1/contacts", options)
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 = DNSimple::Client.get("/v1/contacts/#{id}", options)
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 = DNSimple::Client.get("/v1/contacts", options)
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[DNSimple::Contact.resolve(attribute)] = self.send(attribute)
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 = DNSimple::Client.put("/v1/contacts/#{id}", options)
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
- # Delete the contact from DNSimple. WARNING: this cannot be undone.
147
+ # #delete the contact from DNSimple.
148
+ #
149
+ # WARNING: this cannot be undone.
150
+ #
148
151
  def delete(options={})
149
- DNSimple::Client.delete("/v1/contacts/#{id}", options)
152
+ Client.delete("/v1/contacts/#{id}", options)
150
153
  end
151
154
  alias :destroy :delete
152
155
 
@@ -1,64 +1,66 @@
1
- module DNSimple
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 domain name
8
- attr_accessor :name
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 current known name server status
17
- attr_accessor :name_server_status
10
+ # The Fixnum associated registrant ID.
11
+ attr_accessor :registrant_id
18
12
 
19
- # When the domain is due to expire
20
- attr_accessor :expires_on
13
+ # The String name.
14
+ attr_accessor :name
21
15
 
22
- # The state of the domain in DNSimple
16
+ # The String state.
23
17
  attr_accessor :state
24
18
 
25
- # ID of the registrant in DNSimple
26
- attr_accessor :registrant_id
19
+ # The String API token
20
+ attr_accessor :token
27
21
 
28
- # User ID in DNSimple
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
- # Check the availability of a name
42
- def self.check(name, options={})
43
- response = DNSimple::Client.get("/v1/domains/#{name}/check", options)
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
- "registered"
48
- when 404
49
- "available"
46
+ response.map { |r| new(r["domain"]) }
50
47
  else
51
- raise RequestError.new("Error checking availability", response)
48
+ raise RequestError.new("Error listing domains", response)
52
49
  end
53
50
  end
54
51
 
55
- # Create the domain with the given name in DNSimple. This
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
- response = DNSimple::Client.post("/v1/domains", options)
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 => DNSimple::Contact.resolve_attributes(registrant))
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 = DNSimple::Client.post("/v1/domain_registrations", options)
142
+ response = Client.post("/v1/domain_registrations", options)
85
143
 
86
144
  case response.code
87
145
  when 201
88
- return DNSimple::Domain.new(response["domain"])
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
- # Delete the domain from DNSimple. WARNING: this cannot
134
- # be undone.
135
- def delete(options={})
136
- DNSimple::Client.delete("/v1/domains/#{name}", options)
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
- DNSimple::Client.post("/v1/domains/#{name}/templates/#{template.id}/apply", options)
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 DNSimple::Template
186
+ when Template
152
187
  template
153
188
  else
154
- DNSimple::Template.find(template)
189
+ Template.find(template)
155
190
  end
156
191
  end
157
192
 
158
193
  def applied_services(options={})
159
- response = DNSimple::Client.get("/v1/domains/#{name}/applied_services", options)
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| DNSimple::Service.new(r["service"]) }
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 = DNSimple::Client.get("/v1/domains/#{name}/available_services", options)
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| DNSimple::Service.new(r["service"]) }
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 = DNSimple::Client.post("/v1/domains/#{name}/applied_services", options)
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 = DNSimple::Client.delete("/v1/domains/#{name}/applied_services/#{id}", options)
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 = DNSimple::Client.send(method, "/v1/domains/#{name}/auto_renewal")
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']
@@ -1,4 +1,4 @@
1
- module DNSimple
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 AuthenticationFailed < Error
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 DNSimple
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 << DNSimple::ExtendedAttribute::Option.new(opt)
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 = DNSimple::Client.get("/v1/extended_attributes/#{tld}", options)
41
+ response = Client.get("/v1/extended_attributes/#{tld}", options)
42
42
 
43
43
  case response.code
44
44
  when 200
@@ -1,4 +1,4 @@
1
- module DNSimple
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 !~ DNSimple::BLANK_REGEX }.join(".")
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[DNSimple::Record.resolve(attribute)] = self.send(attribute)
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 = DNSimple::Client.put("/v1/domains/#{domain.id}/records/#{id}", options)
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
- DNSimple::Client.delete("/v1/domains/#{domain.id}/records/#{id}", options)
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
- DNSimple::Record::Aliases[name] || name
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 = DNSimple::Client.post("/v1/domains/#{domain.name}/records", options)
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 = DNSimple::Client.get("/v1/domains/#{domain.name}/records/#{id}", options)
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 = DNSimple::Client.get("/v1/domains/#{domain.name}/records", options)
83
+ response = Client.get("/v1/domains/#{domain.name}/records", options)
84
84
 
85
85
  case response.code
86
86
  when 200