dnsimple 2.0.0.alpha4 → 2.0.0.alpha5

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +22 -2
  3. data/UPGRADING.markdown +102 -0
  4. data/lib/dnsimple/client.rb +37 -16
  5. data/lib/dnsimple/client/certificates.rb +9 -7
  6. data/lib/dnsimple/client/contacts.rb +7 -5
  7. data/lib/dnsimple/client/domains.rb +6 -4
  8. data/lib/dnsimple/client/domains_forwards.rb +6 -6
  9. data/lib/dnsimple/client/domains_records.rb +7 -7
  10. data/lib/dnsimple/client/domains_sharing.rb +4 -4
  11. data/lib/dnsimple/client/domains_zones.rb +1 -1
  12. data/lib/dnsimple/client/name_servers.rb +5 -3
  13. data/lib/dnsimple/client/registrar.rb +20 -7
  14. data/lib/dnsimple/client/services.rb +5 -3
  15. data/lib/dnsimple/client/services_domains.rb +4 -4
  16. data/lib/dnsimple/client/templates.rb +8 -6
  17. data/lib/dnsimple/client/templates_records.rb +7 -7
  18. data/lib/dnsimple/error.rb +1 -1
  19. data/lib/dnsimple/version.rb +1 -1
  20. data/spec/dnsimple/client/certificates_spec.rb +20 -20
  21. data/spec/dnsimple/client/contacts_spec.rb +24 -24
  22. data/spec/dnsimple/client/domains_autorenewals_spec.rb +4 -4
  23. data/spec/dnsimple/client/domains_forwards_spec.rb +17 -17
  24. data/spec/dnsimple/client/domains_privacy_spec.rb +4 -4
  25. data/spec/dnsimple/client/domains_records_spec.rb +20 -20
  26. data/spec/dnsimple/client/domains_sharing_spec.rb +12 -12
  27. data/spec/dnsimple/client/domains_spec.rb +14 -14
  28. data/spec/dnsimple/client/domains_zones_spec.rb +2 -2
  29. data/spec/dnsimple/client/name_servers_spec.rb +13 -13
  30. data/spec/dnsimple/client/registrar_spec.rb +48 -6
  31. data/spec/dnsimple/client/services_spec.rb +11 -11
  32. data/spec/dnsimple/client/templates_records_spec.rb +17 -17
  33. data/spec/dnsimple/client/templates_spec.rb +17 -17
  34. data/spec/dnsimple/client_spec.rb +23 -19
  35. data/spec/files/certificates/{show → get}/success.http +0 -0
  36. data/spec/files/certificates/{index → list}/success.http +0 -0
  37. data/spec/files/contacts/{show → get}/success.http +1 -1
  38. data/spec/files/contacts/{index → list}/success.http +1 -1
  39. data/spec/files/domains/{show → get}/success.http +0 -0
  40. data/spec/files/domains/{index → list}/success.http +0 -0
  41. data/spec/files/domains_records/{show → get}/success.http +0 -0
  42. data/spec/files/domains_records/{index → list}/success.http +0 -0
  43. data/spec/files/services/{show → get}/success.http +0 -0
  44. data/spec/files/services/{index → list}/success.http +0 -0
  45. data/spec/files/subscriptions/{show → get}/success.http +0 -0
  46. data/spec/files/templates/{show → get}/success.http +0 -0
  47. data/spec/files/templates/{index → list}/success.http +0 -0
  48. data/spec/files/templates_records/{show → get}/success.http +0 -0
  49. data/spec/files/templates_records/{index → list}/success.http +0 -0
  50. metadata +33 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29282f721205ff41ca5aacb60da1ea9b1034439b
4
- data.tar.gz: a5ecddeeb95166108c8e94862797901eb8cae133
3
+ metadata.gz: cf0e539a6bca86d40181c2d20b69ca34f8696fdd
4
+ data.tar.gz: c96cf74c57c17745f3c035dc0a38c8719c17c622
5
5
  SHA512:
6
- metadata.gz: 31918228b994c55090c59df96764efc6c5de00b4124629f383f580740c9209a28354a35481c63aab0cf4400b2051b40f844412ee363a6a8990df6aea133ae873
7
- data.tar.gz: 94bd0968025293dfc93acf35834ca3b119c7969bb99acf50854c7db73f8dccfa000d4cf4fde257db4d790f561a4c039e274131c6de81dae970cbc673a9139059
6
+ metadata.gz: b6179bd9c041410c27fd7550745b4a2fe1cca9ecfe193cfca4526064def95cf1817f4f7748baf1aa772671c444915c1ea3c0d77b508e3e7dda84a7bed33c9bd8
7
+ data.tar.gz: 6f1a9ce4b9cd77aa33fbb640e3e1e2613f6c17aeae83098caf53334a514635377850625a9fe4970c1a38beaa74040460aa1de8c9a74be53c519e343b40c19964
data/README.markdown CHANGED
@@ -31,15 +31,35 @@ client = Dnsimple::Client.new(username: 'YOUR_USERNAME', api_token: 'YOUR_TOKEN'
31
31
  user = client.users.user
32
32
  puts "My email is #{user.email}"
33
33
 
34
- # Get a list of your domains
34
+
35
+ # List your domains
35
36
  domains = client.domains.list
36
37
  domains.each do |domain|
37
38
  puts "Domain: %s (id: %d)" % [domain.name, domain.id]
38
39
  end
39
40
 
40
41
  # Create a domain
41
- domain = client.domains.create("example.com")
42
+ domain = client.domains.create(name: "example.com")
43
+ puts "Domain: %s (id: %d)" % [domain.name, domain.id]
44
+
45
+ # Get a domain
46
+ domain = client.domains.domain("example.com")
42
47
  puts "Domain: %s (id: %d)" % [domain.name, domain.id]
48
+
49
+
50
+ # Create a domain record
51
+ record = client.domains.create_record("example.com", record_type: "A", name: "www", content: "127.0.0.1")
52
+ puts "Record: %s (id: %d)" % [record.name, record.id]
53
+
54
+ # Get a domain record
55
+ record = client.domains.record("example.com", 1234)
56
+ puts "Record: %s (id: %d)" % [record.name, record.id]
57
+
58
+ # List domain records
59
+ records = client.domains.records("example.com")
60
+ records.each do |record|
61
+ puts "Record: %s (id: %d)" % [record.name, record.id]
62
+ end
43
63
  ```
44
64
 
45
65
  For the full library documentation visit http://rubydoc.info/gems/dnsimple
@@ -0,0 +1,102 @@
1
+ # Upgrading to v2.0
2
+
3
+ v2.0 is a major upgrade over v1.x and is not backward compatible.
4
+
5
+ The client has been completely rewritten from scratch to provide a more consistent interface
6
+ and take advantage of Ruby 1.9.3 and Ruby 2.0.
7
+
8
+ If you are upgrading your code from v1.x, here's the major changes you should be aware of.
9
+
10
+
11
+ 1. The client is now an instance.
12
+
13
+ All the API calls are performed within the scope of an instance, rather than a class,
14
+ making it possible to pass the client around, write thread-safe code and create multiple client instances
15
+ with different API credentials for a multi-environment application.
16
+
17
+ ```ruby
18
+ # v1
19
+ DNSimple::Client.username = 'YOUR_USERNAME'
20
+ DNSimple::Client.password = 'YOUR_PASSWORD'
21
+ domain = DNSimple::Domain.find("example.com")
22
+
23
+ # v2
24
+ client = Dnsimple::Client.new(username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD')
25
+ domain = client.domains.domain("example.com")
26
+ ```
27
+
28
+ 1. API call responses are now simple struct-like objects, rather Model-like objects.
29
+
30
+ ```ruby
31
+ domain = client.domains.domain("example.com")
32
+ # => Dnsimple::Struct::Domain
33
+ ```
34
+
35
+ A struct-like object is designed to be a simple container of key/value attributes,
36
+ as opposite to a fully-features instance you can interact with.
37
+
38
+ 1. API methods are now defined as methods of the client instance.
39
+
40
+ This is a consequence (or the cause, depending on the POV) of the previous point. It is no longer possible to call
41
+ persistence methods on an object returned from the API, as it was in v1.
42
+
43
+ ```ruby
44
+ record = client.domains.record("example.com", 1)
45
+ # this will fail
46
+ record.name = "www"
47
+ record.update
48
+ ```
49
+
50
+ Instead, treat the object a simple read-only container. If you need to manipulate a Record, Domain or another instance,
51
+ write your own object that encapsulate the desired persistence behavior.
52
+
53
+ Here's a very simple example.
54
+
55
+ ```ruby
56
+ class DnsimpleRecord
57
+ def self.find(client, domain, record_id)
58
+ client.record(domain, record_id)
59
+ end
60
+
61
+ def self.create(client, domain, attributes)
62
+ new(client.create_record(domain, attributes))
63
+ end
64
+
65
+ def initialize(client, instance)
66
+ @client = client
67
+ @instance = instance
68
+ end
69
+
70
+ def update_ip(ip)
71
+ @client.update_record(@instance.domain_id, @instance.record_id, content: ip)
72
+ end
73
+ end
74
+ ```
75
+
76
+ Although this approach seems more verbose at first glance, it encourages the encapsulation of your application logic
77
+ inside custom objects, rather than promoting the patching of the core library objects.
78
+
79
+ Moreover, we found that in most cases developers need access to a very limited set of operations
80
+ rather all the possible API methods attached to a resource. And it's likely you already have a model in your application,
81
+ what you need is just a simple way to interact with the third-party DNSimple application.
82
+
83
+ Last but not least, this approach guarantees that if you want to alter the state of an object and you already know
84
+ its id, you don't need to perform a #find call to instantiate an object to call the update on:
85
+
86
+ ```ruby
87
+ # version 1
88
+ record = Dnsimple::Record.find("example.com", 12)
89
+ record.name = "updated"
90
+ record.content = "127.0.0.1"
91
+ record.update
92
+
93
+ # version 2
94
+ record = Dnsimple::Record.find("example.com", 12)
95
+ record.update(name: "updated", content: "127.0.0.1")
96
+ ```
97
+
98
+ Instead, simply execute
99
+
100
+ ```ruby
101
+ client.domains.update_record("example.com", 12, name: "updated", content: "127.0.0.1")
102
+ ```
@@ -60,7 +60,7 @@ module Dnsimple
60
60
  # @param [Hash] options Query and header params for request
61
61
  # @return [HTTParty::Response]
62
62
  def get(path, options = {})
63
- request :get, path, options
63
+ execute :get, path, options
64
64
  end
65
65
 
66
66
  # Make a HTTP POST request.
@@ -69,7 +69,7 @@ module Dnsimple
69
69
  # @param [Hash] options Body and header params for request
70
70
  # @return [HTTParty::Response]
71
71
  def post(path, options = {})
72
- request :post, path, options
72
+ execute :post, path, options
73
73
  end
74
74
 
75
75
  # Make a HTTP PUT request.
@@ -78,7 +78,7 @@ module Dnsimple
78
78
  # @param [Hash] options Body and header params for request
79
79
  # @return [HTTParty::Response]
80
80
  def put(path, options = {})
81
- request :put, path, options
81
+ execute :put, path, options
82
82
  end
83
83
 
84
84
  # Make a HTTP DELETE request.
@@ -87,26 +87,22 @@ module Dnsimple
87
87
  # @param [Hash] options Query and header params for request
88
88
  # @return [HTTParty::Response]
89
89
  def delete(path, options = {})
90
- request :delete, path, options
90
+ execute :delete, path, options
91
91
  end
92
92
 
93
93
 
94
- # Make a HTTP request.
94
+ # Executes a request, validates and returns the response.
95
95
  #
96
96
  # @param [String] method The HTTP method
97
97
  # @param [String] path The path, relative to {#api_endpoint}
98
98
  # @param [Hash] options Query and header params for request
99
99
  # @return [HTTParty::Response]
100
- def request(method, path, data, options = {})
101
- if data.is_a?(Hash)
102
- options[:query] = data.delete(:query) if data.key?(:query)
103
- options[:headers] = data.delete(:headers) if data.key?(:headers)
104
- end
105
- if !data.empty?
106
- options[:body] = data
107
- end
108
-
109
- response = HTTParty.send(method, api_endpoint + path, Extra.deep_merge!(base_options, options))
100
+ # @raise [RequestError]
101
+ # @raise [NotFoundError]
102
+ # @raise [AuthenticationFailed]
103
+ # @raise [TwoFactorAuthenticationRequired]
104
+ def execute(method, path, data, options = {})
105
+ response = request(method, path, data, options)
110
106
 
111
107
  case response.code
112
108
  when 200..299
@@ -114,13 +110,38 @@ module Dnsimple
114
110
  when 401
115
111
  raise (response.headers[HEADER_OTP_TOKEN] == "required" ? TwoFactorAuthenticationRequired : AuthenticationFailed), response["message"]
116
112
  when 404
117
- raise RecordNotFound.new(response)
113
+ raise NotFoundError.new(response)
118
114
  else
119
115
  raise RequestError.new(response)
120
116
  end
121
117
  end
122
118
 
123
119
 
120
+ # Make a HTTP request.
121
+ #
122
+ # This method doesn't validate the response and never raise errors
123
+ # even in case of HTTP error codes, except for connection errors raised by
124
+ # the underlying HTTP client.
125
+ #
126
+ # Therefore, it's up to the caller to properly handle and validate the response.
127
+ #
128
+ # @param [String] method The HTTP method
129
+ # @param [String] path The path, relative to {#api_endpoint}
130
+ # @param [Hash] options Query and header params for request
131
+ # @return [HTTParty::Response]
132
+ def request(method, path, data, options = {})
133
+ if data.is_a?(Hash)
134
+ options[:query] = data.delete(:query) if data.key?(:query)
135
+ options[:headers] = data.delete(:headers) if data.key?(:headers)
136
+ end
137
+ if !data.empty?
138
+ options[:body] = data
139
+ end
140
+
141
+ HTTParty.send(method, api_endpoint + path, Extra.deep_merge!(base_options, options))
142
+ end
143
+
144
+
124
145
  # @return [String] Base URL for API requests.
125
146
  def api_endpoint
126
147
  File.join(@api_endpoint, "")
@@ -10,14 +10,16 @@ module Dnsimple
10
10
  # @param [Hash] options
11
11
  #
12
12
  # @return [Array<Struct::Certificate>]
13
- # @raise [RecordNotFound]
13
+ # @raise [NotFoundError]
14
14
  # @raise [RequestError] When the request fails.
15
- def list(domain, options = {})
15
+ def certificates(domain, options = {})
16
16
  response = client.get("v1/domains/#{domain}/certificates", options)
17
17
 
18
18
  response.map { |r| Struct::Certificate.new(r["certificate"]) }
19
19
  end
20
20
 
21
+ alias :list :certificates
22
+
21
23
  # Gets a certificate for a domain.
22
24
  #
23
25
  # @see http://developer.dnsimple.com/domains/certificates/#get
@@ -26,9 +28,9 @@ module Dnsimple
26
28
  # @param [Fixnum] certificate_id The certificate ID.
27
29
  #
28
30
  # @return [Struct::Certificate]
29
- # @raise [RecordNotFound]
31
+ # @raise [NotFoundError]
30
32
  # @raise [RequestError] When the request fails.
31
- def find(domain, certificate_id)
33
+ def certificate(domain, certificate_id)
32
34
  response = client.get("v1/domains/#{domain}/certificates/#{certificate_id}")
33
35
 
34
36
  Struct::Certificate.new(response["certificate"])
@@ -54,7 +56,7 @@ module Dnsimple
54
56
  # @param [Fixnum] contact_id The ID of the contact associated to the certificate.
55
57
  #
56
58
  # @return [Struct::Certificate]
57
- # @raise [RecordNotFound]
59
+ # @raise [NotFoundError]
58
60
  # @raise [RequestError] When the request fails.
59
61
  def purchase(domain, name, contact_id, options = {})
60
62
  options = Extra.deep_merge(options, { certificate: { name: name, contact_id: contact_id }})
@@ -69,7 +71,7 @@ module Dnsimple
69
71
  # @param [Fixnum] certificate_id The certificate ID.
70
72
  #
71
73
  # @return [Struct::Certificate]
72
- # @raise [RecordNotFound]
74
+ # @raise [NotFoundError]
73
75
  # @raise [RequestError] When the request fails.
74
76
  def configure(domain, certificate_id)
75
77
  response = client.put("v1/domains/#{domain}/certificates/#{certificate_id}/configure")
@@ -84,7 +86,7 @@ module Dnsimple
84
86
  # @param [Fixnum] email The approver email.
85
87
  #
86
88
  # @return [Struct::Certificate]
87
- # @raise [RecordNotFound]
89
+ # @raise [NotFoundError]
88
90
  # @raise [RequestError] When the request fails.
89
91
  def submit(domain, certificate_id, email)
90
92
  options = { certificate: { approver_email: email }}
@@ -8,12 +8,14 @@ module Dnsimple
8
8
  #
9
9
  # @return [Array<Struct::Contact>]
10
10
  # @raise [RequestError] When the request fails.
11
- def list
11
+ def contacts
12
12
  response = client.get("v1/contacts")
13
13
 
14
14
  response.map { |r| Struct::Contact.new(r["contact"]) }
15
15
  end
16
16
 
17
+ alias :list :contacts
18
+
17
19
  # Creates a contact in the account.
18
20
  #
19
21
  # @see http://developer.dnsimple.com/contacts/#create
@@ -37,9 +39,9 @@ module Dnsimple
37
39
  # @param [Fixnum] contact The contact id.
38
40
  #
39
41
  # @return [Struct::Contact]
40
- # @raise [RecordNotFound]
42
+ # @raise [NotFoundError]
41
43
  # @raise [RequestError] When the request fails.
42
- def find(contact)
44
+ def contact(contact)
43
45
  response = client.get("v1/contacts/#{contact}")
44
46
 
45
47
  Struct::Contact.new(response["contact"])
@@ -53,7 +55,7 @@ module Dnsimple
53
55
  # @param [Hash] attributes
54
56
  #
55
57
  # @return [Struct::Contact]
56
- # @raise [RecordNotFound]
58
+ # @raise [NotFoundError]
57
59
  # @raise [RequestError] When the request fails.
58
60
  def update(contact, attributes = {})
59
61
  options = { contact: attributes }
@@ -71,7 +73,7 @@ module Dnsimple
71
73
  # @param [Fixnum] contact The contact id.
72
74
  #
73
75
  # @return [void]
74
- # @raise [RecordNotFound]
76
+ # @raise [NotFoundError]
75
77
  # @raise [RequestError] When the request fails.
76
78
  def delete(contact)
77
79
  client.delete("v1/contacts/#{contact}")
@@ -8,12 +8,14 @@ module Dnsimple
8
8
  #
9
9
  # @return [Array<Struct::Domain>]
10
10
  # @raise [RequestError] When the request fails.
11
- def list(options = {})
11
+ def domains(options = {})
12
12
  response = client.get("v1/domains", options)
13
13
 
14
14
  response.map { |r| Struct::Domain.new(r["domain"]) }
15
15
  end
16
16
 
17
+ alias :list :domains
18
+
17
19
  # Gets a domain from the account.
18
20
  #
19
21
  # @see http://developer.dnsimple.com/domains/#get
@@ -21,9 +23,9 @@ module Dnsimple
21
23
  # @param [#to_s] domain The domain id or domain name.
22
24
  #
23
25
  # @return [Struct::Domain]
24
- # @raise [RecordNotFound]
26
+ # @raise [NotFoundError]
25
27
  # @raise [RequestError] When the request fails.
26
- def find(domain)
28
+ def domain(domain)
27
29
  response = client.get("v1/domains/#{domain}")
28
30
 
29
31
  Struct::Domain.new(response["domain"])
@@ -54,7 +56,7 @@ module Dnsimple
54
56
  # @param [#to_s] domain The domain id or domain name.
55
57
  #
56
58
  # @return [void]
57
- # @raise [RecordNotFound]
59
+ # @raise [NotFoundError]
58
60
  # @raise [RequestError] When the request fails.
59
61
  def delete(domain)
60
62
  client.delete("v1/domains/#{domain}")
@@ -9,9 +9,9 @@ module Dnsimple
9
9
  # @param [#to_s] domain The domain id or domain name.
10
10
  #
11
11
  # @return [Array<Struct::EmailForward>]
12
- # @raise [RecordNotFound]
12
+ # @raise [NotFoundError]
13
13
  # @raise [RequestError] When the request fails.
14
- def list_email_forwards(domain)
14
+ def email_forwards(domain)
15
15
  response = client.get("v1/domains/#{domain}/email_forwards")
16
16
 
17
17
  response.map { |r| Struct::EmailForward.new(r["email_forward"]) }
@@ -25,7 +25,7 @@ module Dnsimple
25
25
  # @param [Hash] attributes
26
26
  #
27
27
  # @return [Struct::EmailForward]
28
- # @raise [RecordNotFound]
28
+ # @raise [NotFoundError]
29
29
  # @raise [RequestError] When the request fails.
30
30
  def create_email_forward(domain, attributes = {})
31
31
  Extra.validate_mandatory_attributes(attributes, [:from, :to])
@@ -43,9 +43,9 @@ module Dnsimple
43
43
  # @param [Fixnum] forward The forward id.
44
44
  #
45
45
  # @return [Struct::EmailForward]
46
- # @raise [RecordNotFound]
46
+ # @raise [NotFoundError]
47
47
  # @raise [RequestError] When the request fails.
48
- def find_email_forward(domain, forward)
48
+ def email_forward(domain, forward)
49
49
  response = client.get("v1/domains/#{domain}/email_forwards/#{forward}")
50
50
 
51
51
  Struct::EmailForward.new(response["email_forward"])
@@ -59,7 +59,7 @@ module Dnsimple
59
59
  # @param [Fixnum] forward The forward id.
60
60
  #
61
61
  # @return [void]
62
- # @raise [RecordNotFound]
62
+ # @raise [NotFoundError]
63
63
  # @raise [RequestError] When the request fails.
64
64
  def delete_email_forward(domain, forward)
65
65
  client.delete("v1/domains/#{domain}/email_forwards/#{forward}")
@@ -10,9 +10,9 @@ module Dnsimple
10
10
  # @param [Hash] options
11
11
  #
12
12
  # @return [Array<Struct::Record>]
13
- # @raise [RecordNotFound]
13
+ # @raise [NotFoundError]
14
14
  # @raise [RequestError] When the request fails.
15
- def list_records(domain, options = {})
15
+ def records(domain, options = {})
16
16
  response = client.get("v1/domains/#{domain}/records", options)
17
17
 
18
18
  response.map { |r| Struct::Record.new(r["record"]) }
@@ -26,7 +26,7 @@ module Dnsimple
26
26
  # @param [Hash] attributes
27
27
  #
28
28
  # @return [Struct::Record]
29
- # @raise [RecordNotFound]
29
+ # @raise [NotFoundError]
30
30
  # @raise [RequestError] When the request fails.
31
31
  def create_record(domain, attributes = {})
32
32
  Extra.validate_mandatory_attributes(attributes, [:name, :record_type, :content])
@@ -44,9 +44,9 @@ module Dnsimple
44
44
  # @param [Fixnum] record The record id.
45
45
  #
46
46
  # @return [Struct::Record]
47
- # @raise [RecordNotFound]
47
+ # @raise [NotFoundError]
48
48
  # @raise [RequestError] When the request fails.
49
- def find_record(domain, record)
49
+ def record(domain, record)
50
50
  response = client.get("v1/domains/#{domain}/records/#{record}")
51
51
 
52
52
  Struct::Record.new(response["record"])
@@ -61,7 +61,7 @@ module Dnsimple
61
61
  # @param [Hash] attributes
62
62
  #
63
63
  # @return [Struct::Record]
64
- # @raise [RecordNotFound]
64
+ # @raise [NotFoundError]
65
65
  # @raise [RequestError] When the request fails.
66
66
  def update_record(domain, record, attributes = {})
67
67
  options = { record: attributes }
@@ -78,7 +78,7 @@ module Dnsimple
78
78
  # @param [Fixnum] record The record id.
79
79
  #
80
80
  # @return [void]
81
- # @raise [RecordNotFound]
81
+ # @raise [NotFoundError]
82
82
  # @raise [RequestError] When the request fails.
83
83
  def delete_record(domain, record)
84
84
  client.delete("v1/domains/#{domain}/records/#{record}")