dnsimple 2.0.0.alpha4 → 2.0.0.alpha5

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