dnsimple 2.0.0.a
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.markdown +50 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.markdown +60 -0
- data/Rakefile +33 -0
- data/dnsimple-ruby.gemspec +26 -0
- data/lib/dnsimple-ruby.rb +1 -0
- data/lib/dnsimple.rb +33 -0
- data/lib/dnsimple/base.rb +10 -0
- data/lib/dnsimple/certificate.rb +129 -0
- data/lib/dnsimple/client.rb +144 -0
- data/lib/dnsimple/contact.rb +154 -0
- data/lib/dnsimple/domain.rb +217 -0
- data/lib/dnsimple/error.rb +21 -0
- data/lib/dnsimple/extended_attribute.rb +52 -0
- data/lib/dnsimple/record.rb +94 -0
- data/lib/dnsimple/service.rb +42 -0
- data/lib/dnsimple/template.rb +63 -0
- data/lib/dnsimple/template_record.rb +80 -0
- data/lib/dnsimple/transfer_order.rb +34 -0
- data/lib/dnsimple/user.rb +26 -0
- data/lib/dnsimple/version.rb +3 -0
- data/spec/ci/.dnsimple.test +3 -0
- data/spec/dnsimple/certificate_spec.rb +56 -0
- data/spec/dnsimple/client_spec.rb +107 -0
- data/spec/dnsimple/contact_spec.rb +45 -0
- data/spec/dnsimple/domain_spec.rb +133 -0
- data/spec/dnsimple/extended_attributes_spec.rb +54 -0
- data/spec/dnsimple/record_spec.rb +51 -0
- data/spec/dnsimple/template_spec.rb +31 -0
- data/spec/dnsimple/user_spec.rb +31 -0
- data/spec/files/account/user/success.http +19 -0
- data/spec/files/certificates/index/success.http +19 -0
- data/spec/files/certificates/show/notfound.http +17 -0
- data/spec/files/certificates/show/success.http +19 -0
- data/spec/files/contacts/show/notfound.http +17 -0
- data/spec/files/contacts/show/success.http +19 -0
- data/spec/files/domains/auto_renewal_disable/notfound.http +21 -0
- data/spec/files/domains/auto_renewal_disable/success.http +23 -0
- data/spec/files/domains/auto_renewal_enable/notfound.http +21 -0
- data/spec/files/domains/auto_renewal_enable/success.http +23 -0
- data/spec/files/domains/show/notfound.http +17 -0
- data/spec/files/domains/show/success.http +19 -0
- data/spec/files/extended_attributes/ca.http +19 -0
- data/spec/files/extended_attributes/com.http +19 -0
- data/spec/files/extended_attributes/success.http +19 -0
- data/spec/files/records/index/success.http +19 -0
- data/spec/files/records/show/notfound.http +17 -0
- data/spec/files/records/show/success.http +19 -0
- data/spec/files/templates/show/notfound.http +17 -0
- data/spec/files/templates/show/success.http +19 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/support/helpers.rb +15 -0
- data/spec/support/webmock.rb +11 -0
- metadata +224 -0
@@ -0,0 +1,154 @@
|
|
1
|
+
module DNSimple
|
2
|
+
|
3
|
+
# Represents a contact.
|
4
|
+
class Contact < Base
|
5
|
+
|
6
|
+
Aliases = {
|
7
|
+
'first' => 'first_name',
|
8
|
+
'last' => 'last_name',
|
9
|
+
'state' => 'state_province',
|
10
|
+
'province' => 'state_province',
|
11
|
+
'state_or_province' => 'state_province',
|
12
|
+
'email' => 'email_address',
|
13
|
+
}
|
14
|
+
|
15
|
+
# The contact ID in DNSimple
|
16
|
+
attr_accessor :id
|
17
|
+
|
18
|
+
# The contact first name
|
19
|
+
attr_accessor :first_name
|
20
|
+
|
21
|
+
# The contact last name
|
22
|
+
attr_accessor :last_name
|
23
|
+
|
24
|
+
# The contact's job title
|
25
|
+
attr_accessor :job_title
|
26
|
+
|
27
|
+
# The name of the organization in which the contact works
|
28
|
+
attr_accessor :organization_name
|
29
|
+
|
30
|
+
# The contact email address
|
31
|
+
attr_accessor :email_address
|
32
|
+
|
33
|
+
# The contact phone number
|
34
|
+
attr_accessor :phone
|
35
|
+
|
36
|
+
# The contact phone extension (may be omitted)
|
37
|
+
attr_accessor :phone_ext
|
38
|
+
|
39
|
+
# The contact fax number (may be omitted)
|
40
|
+
attr_accessor :fax
|
41
|
+
|
42
|
+
# The contact street address
|
43
|
+
attr_accessor :address1
|
44
|
+
|
45
|
+
# Apartment or suite number
|
46
|
+
attr_accessor :address2
|
47
|
+
|
48
|
+
# The city name
|
49
|
+
attr_accessor :city
|
50
|
+
|
51
|
+
# The state or province name
|
52
|
+
attr_accessor :state_province
|
53
|
+
|
54
|
+
# The contact postal code
|
55
|
+
attr_accessor :postal_code
|
56
|
+
|
57
|
+
# The contact country (as a 2-character country code)
|
58
|
+
attr_accessor :country
|
59
|
+
|
60
|
+
# When the contact was created in DNSimple
|
61
|
+
attr_accessor :created_at
|
62
|
+
|
63
|
+
# When the contact was last updated in DNSimple
|
64
|
+
attr_accessor :updated_at
|
65
|
+
|
66
|
+
|
67
|
+
# Map an aliased field name to it's real name. For example, if you
|
68
|
+
# pass "first" it will be resolved to "first_name", "email" is resolved
|
69
|
+
# to "email_address" and so on.
|
70
|
+
def self.resolve(name)
|
71
|
+
DNSimple::Contact::Aliases[name.to_s] || name
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.resolve_attributes(attributes)
|
75
|
+
resolved_attributes = {}
|
76
|
+
attributes.each do |k, v|
|
77
|
+
resolved_attributes[resolve(k)] = v
|
78
|
+
end
|
79
|
+
resolved_attributes
|
80
|
+
end
|
81
|
+
|
82
|
+
# Create the contact with the given attributes in DNSimple.
|
83
|
+
# This method returns a Contact instance of the contact is created
|
84
|
+
# and raises an error otherwise.
|
85
|
+
def self.create(attributes, options={})
|
86
|
+
contact_hash = resolve_attributes(attributes)
|
87
|
+
|
88
|
+
options.merge!({:body => {:contact => contact_hash}})
|
89
|
+
response = DNSimple::Client.post("/v1/contacts", options)
|
90
|
+
|
91
|
+
case response.code
|
92
|
+
when 201
|
93
|
+
new(response["contact"])
|
94
|
+
else
|
95
|
+
raise RequestError.new("Error creating contact", response)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.find(id, options={})
|
100
|
+
response = DNSimple::Client.get("/v1/contacts/#{id}", options)
|
101
|
+
|
102
|
+
case response.code
|
103
|
+
when 200
|
104
|
+
new(response["contact"])
|
105
|
+
when 404
|
106
|
+
raise RecordNotFound, "Could not find contact #{id}"
|
107
|
+
else
|
108
|
+
raise RequestError.new("Error finding contact", response)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.all(options={})
|
113
|
+
response = DNSimple::Client.get("/v1/contacts", options)
|
114
|
+
|
115
|
+
case response.code
|
116
|
+
when 200
|
117
|
+
response.map { |r| new(r["contact"]) }
|
118
|
+
else
|
119
|
+
raise RequestError.new("Error listing contacts", response)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
def name
|
125
|
+
[first_name, last_name].join(' ')
|
126
|
+
end
|
127
|
+
|
128
|
+
def save(options={})
|
129
|
+
contact_hash = {}
|
130
|
+
%w(first_name last_name organization_name job_title address1 address2 city
|
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)
|
133
|
+
end
|
134
|
+
|
135
|
+
options.merge!({:body => {:contact => contact_hash}})
|
136
|
+
|
137
|
+
response = DNSimple::Client.put("/v1/contacts/#{id}", options)
|
138
|
+
|
139
|
+
case response.code
|
140
|
+
when 200
|
141
|
+
return self
|
142
|
+
else
|
143
|
+
raise RequestError.new("Error updating contact", response)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Delete the contact from DNSimple. WARNING: this cannot be undone.
|
148
|
+
def delete(options={})
|
149
|
+
DNSimple::Client.delete("/v1/contacts/#{id}", options)
|
150
|
+
end
|
151
|
+
alias :destroy :delete
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module DNSimple
|
2
|
+
class Domain < Base
|
3
|
+
|
4
|
+
# The domain ID in DNSimple
|
5
|
+
attr_accessor :id
|
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
|
15
|
+
|
16
|
+
# The current known name server status
|
17
|
+
attr_accessor :name_server_status
|
18
|
+
|
19
|
+
# When the domain is due to expire
|
20
|
+
attr_accessor :expires_on
|
21
|
+
|
22
|
+
# The state of the domain in DNSimple
|
23
|
+
attr_accessor :state
|
24
|
+
|
25
|
+
# ID of the registrant in DNSimple
|
26
|
+
attr_accessor :registrant_id
|
27
|
+
|
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
|
35
|
+
attr_accessor :auto_renew
|
36
|
+
|
37
|
+
# Is the whois information protected
|
38
|
+
attr_accessor :whois_protected
|
39
|
+
|
40
|
+
|
41
|
+
# Check the availability of a name
|
42
|
+
def self.check(name, options={})
|
43
|
+
response = DNSimple::Client.get("/v1/domains/#{name}/check", options)
|
44
|
+
|
45
|
+
case response.code
|
46
|
+
when 200
|
47
|
+
"registered"
|
48
|
+
when 404
|
49
|
+
"available"
|
50
|
+
else
|
51
|
+
raise RequestError.new("Error checking availability", response)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
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}}})
|
60
|
+
|
61
|
+
response = DNSimple::Client.post("/v1/domains", options)
|
62
|
+
|
63
|
+
case response.code
|
64
|
+
when 201
|
65
|
+
new(response["domain"])
|
66
|
+
else
|
67
|
+
raise RequestError.new("Error creating domain", response)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Purchase a domain name.
|
72
|
+
def self.register(name, registrant={}, extended_attributes={}, options={})
|
73
|
+
body = {:domain => {:name => name}}
|
74
|
+
if registrant
|
75
|
+
if registrant[:id]
|
76
|
+
body[:domain][:registrant_id] = registrant[:id]
|
77
|
+
else
|
78
|
+
body.merge!(:contact => DNSimple::Contact.resolve_attributes(registrant))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
body.merge!(:extended_attribute => extended_attributes)
|
82
|
+
options.merge!({:body => body})
|
83
|
+
|
84
|
+
response = DNSimple::Client.post("/v1/domain_registrations", options)
|
85
|
+
|
86
|
+
case response.code
|
87
|
+
when 201
|
88
|
+
return DNSimple::Domain.new(response["domain"])
|
89
|
+
else
|
90
|
+
raise RequestError.new("Error registering domain", response)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
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
|
+
|
121
|
+
# Enable auto_renew on the domain
|
122
|
+
def enable_auto_renew
|
123
|
+
return if auto_renew
|
124
|
+
auto_renew!(:post)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Disable auto_renew on the domain
|
128
|
+
def disable_auto_renew
|
129
|
+
return unless auto_renew
|
130
|
+
auto_renew!(:delete)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Delete the domain from DNSimple. WARNING: this cannot
|
134
|
+
# be undone.
|
135
|
+
def delete(options={})
|
136
|
+
DNSimple::Client.delete("/v1/domains/#{name}", options)
|
137
|
+
end
|
138
|
+
alias :destroy :delete
|
139
|
+
|
140
|
+
# Apply the given named template to the domain. This will add
|
141
|
+
# all of the records in the template to the domain.
|
142
|
+
def apply(template, options={})
|
143
|
+
options.merge!(:body => {})
|
144
|
+
template = resolve_template(template)
|
145
|
+
|
146
|
+
DNSimple::Client.post("/v1/domains/#{name}/templates/#{template.id}/apply", options)
|
147
|
+
end
|
148
|
+
|
149
|
+
def resolve_template(template)
|
150
|
+
case template
|
151
|
+
when DNSimple::Template
|
152
|
+
template
|
153
|
+
else
|
154
|
+
DNSimple::Template.find(template)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def applied_services(options={})
|
159
|
+
response = DNSimple::Client.get("/v1/domains/#{name}/applied_services", options)
|
160
|
+
|
161
|
+
case response.code
|
162
|
+
when 200
|
163
|
+
response.map { |r| DNSimple::Service.new(r["service"]) }
|
164
|
+
else
|
165
|
+
raise RequestError.new("Error listing applied services", response)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def available_services(options={})
|
170
|
+
response = DNSimple::Client.get("/v1/domains/#{name}/available_services", options)
|
171
|
+
|
172
|
+
case response.code
|
173
|
+
when 200
|
174
|
+
response.map { |r| DNSimple::Service.new(r["service"]) }
|
175
|
+
else
|
176
|
+
raise RequestError.new("Error listing available services", response)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def add_service(id_or_short_name, options={})
|
181
|
+
options.merge!(:body => {:service => {:id => id_or_short_name}})
|
182
|
+
response = DNSimple::Client.post("/v1/domains/#{name}/applied_services", options)
|
183
|
+
|
184
|
+
case response.code
|
185
|
+
when 200
|
186
|
+
true
|
187
|
+
else
|
188
|
+
raise RequestError.new("Error adding service", response)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def remove_service(id, options={})
|
193
|
+
response = DNSimple::Client.delete("/v1/domains/#{name}/applied_services/#{id}", options)
|
194
|
+
|
195
|
+
case response.code
|
196
|
+
when 200
|
197
|
+
true
|
198
|
+
else
|
199
|
+
raise RequestError.new("Error removing service", response)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
private
|
205
|
+
|
206
|
+
def auto_renew!(method)
|
207
|
+
response = DNSimple::Client.send(method, "/v1/domains/#{name}/auto_renewal")
|
208
|
+
case response.code
|
209
|
+
when 200
|
210
|
+
self.auto_renew = response['domain']['auto_renew']
|
211
|
+
else
|
212
|
+
raise RequestError.new("Error setting auto_renew", response)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DNSimple
|
2
|
+
|
3
|
+
class Error < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class RecordExists < Error
|
7
|
+
end
|
8
|
+
|
9
|
+
class RecordNotFound < Error
|
10
|
+
end
|
11
|
+
|
12
|
+
class RequestError < Error
|
13
|
+
def initialize(description, response)
|
14
|
+
super("#{description}: #{response["error"]}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class AuthenticationFailed < Error
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module DNSimple
|
2
|
+
|
3
|
+
# Used for domains that require extended attributes.
|
4
|
+
class ExtendedAttribute < Base
|
5
|
+
|
6
|
+
# An option for an extended attribute
|
7
|
+
class Option < Base
|
8
|
+
# The option name
|
9
|
+
attr_accessor :title
|
10
|
+
|
11
|
+
# The option value
|
12
|
+
attr_accessor :value
|
13
|
+
|
14
|
+
# A long description of the option
|
15
|
+
attr_accessor :description
|
16
|
+
end
|
17
|
+
|
18
|
+
# The extended attribute name
|
19
|
+
attr_accessor :name
|
20
|
+
|
21
|
+
# A description of the extended attribute
|
22
|
+
attr_accessor :description
|
23
|
+
|
24
|
+
# Boolean indicating if the extended attribute is required
|
25
|
+
attr_accessor :required
|
26
|
+
|
27
|
+
# An array of options for the extended attribute
|
28
|
+
def options
|
29
|
+
@options ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
def options=(opts)
|
33
|
+
@options = []
|
34
|
+
opts.each do |opt|
|
35
|
+
@options << DNSimple::ExtendedAttribute::Option.new(opt)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Find the extended attributes for the given TLD
|
40
|
+
def self.find(tld, options={})
|
41
|
+
response = DNSimple::Client.get("/v1/extended_attributes/#{tld}", options)
|
42
|
+
|
43
|
+
case response.code
|
44
|
+
when 200
|
45
|
+
response.map { |r| new(r) }
|
46
|
+
else
|
47
|
+
raise RequestError.new("Error finding extended attributes", response)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module DNSimple
|
2
|
+
|
3
|
+
class Record < Base
|
4
|
+
Aliases = {
|
5
|
+
'priority' => 'prio',
|
6
|
+
'time-to-live' => 'ttl'
|
7
|
+
}
|
8
|
+
|
9
|
+
attr_accessor :id
|
10
|
+
attr_accessor :domain
|
11
|
+
attr_accessor :name
|
12
|
+
attr_accessor :content
|
13
|
+
attr_accessor :ttl
|
14
|
+
attr_accessor :prio
|
15
|
+
attr_accessor :record_type
|
16
|
+
|
17
|
+
|
18
|
+
def fqdn
|
19
|
+
[name, domain.name].delete_if { |v| v !~ DNSimple::BLANK_REGEX }.join(".")
|
20
|
+
end
|
21
|
+
|
22
|
+
def save(options={})
|
23
|
+
record_hash = {}
|
24
|
+
%w(name content ttl prio).each do |attribute|
|
25
|
+
record_hash[DNSimple::Record.resolve(attribute)] = self.send(attribute)
|
26
|
+
end
|
27
|
+
|
28
|
+
options.merge!(:body => {:record => record_hash})
|
29
|
+
|
30
|
+
response = DNSimple::Client.put("/v1/domains/#{domain.id}/records/#{id}", options)
|
31
|
+
|
32
|
+
case response.code
|
33
|
+
when 200
|
34
|
+
self
|
35
|
+
else
|
36
|
+
raise RequestError.new("Error updating record", response)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(options={})
|
41
|
+
DNSimple::Client.delete("/v1/domains/#{domain.id}/records/#{id}", options)
|
42
|
+
end
|
43
|
+
alias :destroy :delete
|
44
|
+
|
45
|
+
def self.resolve(name)
|
46
|
+
DNSimple::Record::Aliases[name] || name
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.create(domain, name, record_type, content, options={})
|
50
|
+
record_hash = {:name => name, :record_type => record_type, :content => content}
|
51
|
+
record_hash[:ttl] = options.delete(:ttl) || 3600
|
52
|
+
record_hash[:prio] = options.delete(:priority)
|
53
|
+
record_hash[:prio] = options.delete(:prio) || ''
|
54
|
+
|
55
|
+
options.merge!({:body => {:record => record_hash}})
|
56
|
+
|
57
|
+
response = DNSimple::Client.post("/v1/domains/#{domain.name}/records", options)
|
58
|
+
|
59
|
+
case response.code
|
60
|
+
when 201
|
61
|
+
new({:domain => domain}.merge(response["record"]))
|
62
|
+
when 406
|
63
|
+
raise RecordExists, "Record #{name}.#{domain.name} already exists"
|
64
|
+
else
|
65
|
+
raise RequestError.new("Error creating record", response)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.find(domain, id, options={})
|
70
|
+
response = DNSimple::Client.get("/v1/domains/#{domain.name}/records/#{id}", options)
|
71
|
+
|
72
|
+
case response.code
|
73
|
+
when 200
|
74
|
+
new({:domain => domain}.merge(response["record"]))
|
75
|
+
when 404
|
76
|
+
raise RecordNotFound, "Could not find record #{id} for domain #{domain.name}"
|
77
|
+
else
|
78
|
+
raise RequestError.new("Error finding record", response)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.all(domain, options={})
|
83
|
+
response = DNSimple::Client.get("/v1/domains/#{domain.name}/records", options)
|
84
|
+
|
85
|
+
case response.code
|
86
|
+
when 200
|
87
|
+
response.map { |r| new({:domain => domain}.merge(r["record"])) }
|
88
|
+
else
|
89
|
+
raise RequestError.new("Error listing records", response)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|