dnsmadeeasy-api 0.9
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.
- data/Manifest +6 -0
- data/README.rdoc +37 -0
- data/Rakefile +17 -0
- data/bin/dme +244 -0
- data/dnsmadeeasy-api.gemspec +46 -0
- data/lib/dnsmadeeasy/api.rb +275 -0
- data/lib/dnsmadeeasy/exceptions.rb +44 -0
- metadata +138 -0
data/Manifest
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
= DnsMadeEasy/API
|
3
|
+
|
4
|
+
Ruby client for DNSMadeEasy API.
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
# gem install environment
|
9
|
+
|
10
|
+
== Usage
|
11
|
+
|
12
|
+
require "rubygems"
|
13
|
+
require "dnsmadeeasy/api"
|
14
|
+
|
15
|
+
api_key = <your dnsmadeeasy api key>
|
16
|
+
secret_ket = <your dnsmadeeasy secret key>
|
17
|
+
api = DnsMadeEasy::Api(api_key, secret_key)
|
18
|
+
api.list_records "sigfig.com"
|
19
|
+
|
20
|
+
To run in sandbox mode (you need an account and api key at sandbox.dnsmadeeasy.com).
|
21
|
+
This is a great way to test your application without changing your production DNS entries.
|
22
|
+
|
23
|
+
api = DnsMadeEasy::Api(api_key, secret_key, true)
|
24
|
+
api.list_records "sigfig.com"
|
25
|
+
|
26
|
+
== Command line tool
|
27
|
+
|
28
|
+
The client comes with a command line tool "dme". Use "dme --help" to see how to use the command.
|
29
|
+
The command line tool requires that your api credentials be stored in /etc/dnsmadeeasy/api.keys as
|
30
|
+
api_key=<api_key>
|
31
|
+
secret_key=<secret_key>
|
32
|
+
|
33
|
+
The command line tool also allows the running of queries in the sandbox mode. To do so, create
|
34
|
+
/etc/dnsmadeeasy/api_sandbox.keys with your sandbox api key and secret key and use the --sandbox option
|
35
|
+
with every command.
|
36
|
+
|
37
|
+
=end
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake"
|
3
|
+
require "echoe"
|
4
|
+
|
5
|
+
Echoe.new("dnsmadeeasy-api", "0.9") do |p|
|
6
|
+
p.description = "Ruby client for DNSMadeEasy API."
|
7
|
+
p.summary = "Ruby client for DNSMadeEasy API."
|
8
|
+
p.url = "http://rubygems.org/gems/dnsmadeeasy-api"
|
9
|
+
p.author = "Nitesh Goel"
|
10
|
+
p.email = "nitesh@wikinvest.com"
|
11
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
12
|
+
p.install_message = "Create /etc/dnsmadeeasy/api.keys and/or /etc/dnsmadeeasy/api_sandbox.keys with the following information\napi_key=<your api key>\nsecret_key=<your secret key>\nto use the dme binary."
|
13
|
+
p.runtime_dependencies = ["rest-client", "json"]
|
14
|
+
p.development_dependencies = ["rake", "echoe"]
|
15
|
+
end
|
16
|
+
|
17
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/bin/dme
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubygems"
|
3
|
+
require "dnsmadeeasy/api"
|
4
|
+
require "json"
|
5
|
+
require "optparse"
|
6
|
+
|
7
|
+
class Array
|
8
|
+
def to_s
|
9
|
+
join(", ")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module DnsMadeEasy
|
14
|
+
class Printer
|
15
|
+
attr_accessor :json
|
16
|
+
|
17
|
+
def initialize(json=false)
|
18
|
+
@json = json
|
19
|
+
end
|
20
|
+
|
21
|
+
def help_text
|
22
|
+
valid_commands = {
|
23
|
+
"list-domains" => "List all domains in the account",
|
24
|
+
"delete-domains" => "Delete all domains in the account",
|
25
|
+
"create-domain" => "Create a new domain entry",
|
26
|
+
"delete-domain" => "Delete a domain entry",
|
27
|
+
"describe-domain" => "Describe a domain entry",
|
28
|
+
"list-records" => "List records for a domain",
|
29
|
+
"create-record" => "Create a new dns record",
|
30
|
+
"delete-record" => "Delete a dns record",
|
31
|
+
"update-record" => "Update an existing dns record",
|
32
|
+
"describe-record" => "Describe an existing dns record"
|
33
|
+
}
|
34
|
+
help = "Usage: dme command [options]"
|
35
|
+
help << "\nValid commands\n"
|
36
|
+
valid_commands.each do |name, description|
|
37
|
+
help << "\t#{name.ljust(18)}=> #{description}\n"
|
38
|
+
end
|
39
|
+
return help
|
40
|
+
end
|
41
|
+
|
42
|
+
def show_error(message)
|
43
|
+
if @json
|
44
|
+
output = { "error" => message }
|
45
|
+
puts output.to_json
|
46
|
+
else
|
47
|
+
puts "ERROR: #{message}"
|
48
|
+
end
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
|
52
|
+
def say_bye(message)
|
53
|
+
puts message
|
54
|
+
exit 0
|
55
|
+
end
|
56
|
+
|
57
|
+
def show_response(response)
|
58
|
+
if @json
|
59
|
+
if response.is_a?(TrueClass) || response.is_a?(FalseClass)
|
60
|
+
response = { :success => response }
|
61
|
+
end
|
62
|
+
puts response.to_json
|
63
|
+
elsif response.is_a?(TrueClass) || response.is_a?(FalseClass)
|
64
|
+
if response
|
65
|
+
puts "Done"
|
66
|
+
else
|
67
|
+
puts "Not done"
|
68
|
+
end
|
69
|
+
elsif response.instance_of?(Array) && response[0].instance_of?(String)
|
70
|
+
response.each do |x|
|
71
|
+
puts x
|
72
|
+
end
|
73
|
+
else
|
74
|
+
table_fields = {}
|
75
|
+
response = [response] if response.instance_of?(Hash)
|
76
|
+
response.each do |x|
|
77
|
+
x.each do |key, value|
|
78
|
+
table_fields[key] ||= []
|
79
|
+
table_fields[key] << value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
max_widths = {}
|
83
|
+
table_fields.each do |key, values|
|
84
|
+
max_width = values.inject(key.to_s.length) { |length, s| [length, s.to_s.length].max }
|
85
|
+
max_widths[key] = max_width
|
86
|
+
end
|
87
|
+
#puts max_widths.inspect
|
88
|
+
row = []
|
89
|
+
table_fields.to_a.each do |column|
|
90
|
+
row[0] ||= []
|
91
|
+
row[0] << column[0].to_s.upcase.ljust(max_widths[column[0]])
|
92
|
+
column[1].each_index do |x|
|
93
|
+
row[x+1] ||= []
|
94
|
+
row[x+1] << column[1][x].to_s.ljust(max_widths[column[0]])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
#puts row.inspect
|
98
|
+
#exit
|
99
|
+
row.map! { |x| "| #{x.join(' | ')} |" }
|
100
|
+
rows = row.length
|
101
|
+
row_length = row[0].length
|
102
|
+
divider = "-"*row_length
|
103
|
+
row.each_index do |x|
|
104
|
+
if x.zero?
|
105
|
+
puts divider
|
106
|
+
puts row[x]
|
107
|
+
puts divider
|
108
|
+
elsif x == rows-1
|
109
|
+
puts row[x]
|
110
|
+
puts divider
|
111
|
+
else
|
112
|
+
puts row[x]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
printer = DnsMadeEasy::Printer.new
|
121
|
+
|
122
|
+
# process input
|
123
|
+
domain = nil
|
124
|
+
options = {}
|
125
|
+
force = false
|
126
|
+
record_id = nil
|
127
|
+
sandbox = false
|
128
|
+
optparse = OptionParser.new do |opts|
|
129
|
+
opts.banner = printer.help_text + "\nOptions\n"
|
130
|
+
opts.on("-f", "--force", "Force operation") do
|
131
|
+
force = true
|
132
|
+
end
|
133
|
+
opts.on("-j", "--json", "Format output as json") do
|
134
|
+
printer.json = true
|
135
|
+
end
|
136
|
+
opts.on("-s", "--sandbox", "Run the sandbox api") do
|
137
|
+
sandbox = true
|
138
|
+
end
|
139
|
+
opts.on("-d", "--domain DOMAIN", "Domain Name") do |d|
|
140
|
+
domain = d
|
141
|
+
end
|
142
|
+
opts.on("-n", "--name HOSTNAME", "Hostname") do |h|
|
143
|
+
options[:name] = h
|
144
|
+
end
|
145
|
+
opts.on("-v", "--value VALUE", "The destination of the entry (IP/relative hostname/hostname)") do |v|
|
146
|
+
options[:data] = v
|
147
|
+
end
|
148
|
+
opts.on("-g", "--gtd GTD", "GTD Location") do |g|
|
149
|
+
options[:gtdLocation] = g
|
150
|
+
end
|
151
|
+
opts.on("-t", "--type TYPE", "The type of dns record") do |t|
|
152
|
+
options[:type] = t.upcase.to_sym
|
153
|
+
end
|
154
|
+
opts.on("-l", "--ttl TTL", "Time to live") do |l|
|
155
|
+
options[:ttl] = l
|
156
|
+
end
|
157
|
+
opts.on("-r", "--record RECORD", "Record id") do |r|
|
158
|
+
record_id = r
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
optparse.parse!
|
163
|
+
|
164
|
+
auth_file = sandbox ? "/etc/dnsmadeeasy/api_sandbox.keys" : "/etc/dnsmadeeasy/api.keys"
|
165
|
+
begin
|
166
|
+
auth_contents = File.read(auth_file)
|
167
|
+
auth_hash = Hash[auth_contents.split("\n").map { |x| x.split("=") }]
|
168
|
+
api_key = auth_hash["api_key"]
|
169
|
+
secret_key = auth_hash["secret_key"]
|
170
|
+
if api_key.nil? || secret_key.nil?
|
171
|
+
throw new StandardError
|
172
|
+
end
|
173
|
+
rescue StandardError => e
|
174
|
+
puts e.inspect
|
175
|
+
printer.show_error "Please create a file #{auth_file} with the following information\napi_key=<your api key>\nsecret_key=<your secret key>"
|
176
|
+
end
|
177
|
+
|
178
|
+
api = DnsMadeEasy::Api.new(api_key, secret_key, sandbox)
|
179
|
+
|
180
|
+
command = ARGV.shift
|
181
|
+
|
182
|
+
begin
|
183
|
+
case command
|
184
|
+
when "list-domains"
|
185
|
+
printer.show_response api.list_domains
|
186
|
+
when "delete-domains"
|
187
|
+
unless force
|
188
|
+
puts "The following domains are listed in your account:"
|
189
|
+
printer.show_response api.list_domains
|
190
|
+
puts "Are you sure you want to delete all domains? (yes/no)"
|
191
|
+
response = STDIN.gets.chomp.downcase
|
192
|
+
unless response.downcase == "yes"
|
193
|
+
printer.say_bye "Domains not deleted"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
printer.show_response api.delete_domains!
|
197
|
+
when "create-domain"
|
198
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
199
|
+
printer.show_response api.create_domain!(domain)
|
200
|
+
when "delete-domain"
|
201
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
202
|
+
unless force
|
203
|
+
puts "Are you sure you want to delete #{domain}? (yes/no)"
|
204
|
+
response = STDIN.gets.chomp.downcase
|
205
|
+
unless response.downcase == "yes"
|
206
|
+
printer.say_bye "Domain #{domain} not deleted"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
printer.show_response api.delete_domain!(domain)
|
210
|
+
when "describe-domain"
|
211
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
212
|
+
printer.show_response api.describe_domain(domain)
|
213
|
+
when "list-records"
|
214
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
215
|
+
printer.show_response api.list_records(domain, options)
|
216
|
+
when "create-record"
|
217
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
218
|
+
printer.show_response api.create_record!(domain, options)
|
219
|
+
when "delete-record"
|
220
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
221
|
+
printer.show_response api.describe_record(domain, record_id)
|
222
|
+
unless force
|
223
|
+
puts "Are you sure you want to delete this record? (yes/no)"
|
224
|
+
response = STDIN.gets.chomp.downcase
|
225
|
+
unless response.downcase == "yes"
|
226
|
+
printer.say_bye "Record not deleted"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
printer.show_response api.delete_record!(domain, record_id)
|
230
|
+
when "update-record"
|
231
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
232
|
+
printer.show_response api.update_record!(domain, record_id, options)
|
233
|
+
when "describe-record"
|
234
|
+
printer.show_error "Please specify a domain name" if domain.nil?
|
235
|
+
printer.show_response api.describe_record(domain, record_id)
|
236
|
+
when "help"
|
237
|
+
help_for_command = ARGV.shift
|
238
|
+
|
239
|
+
else
|
240
|
+
printer.show_error "Please enter a valid command"
|
241
|
+
end
|
242
|
+
rescue DnsMadeEasy::RequestFailedError => e
|
243
|
+
printer.show_error e.message
|
244
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{dnsmadeeasy-api}
|
5
|
+
s.version = "0.9"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = [%q{Nitesh Goel}]
|
9
|
+
s.date = %q{2011-07-06}
|
10
|
+
s.description = %q{Ruby client for DNSMadeEasy API.}
|
11
|
+
s.email = %q{nitesh@wikinvest.com}
|
12
|
+
s.executables = [%q{dme}]
|
13
|
+
s.extra_rdoc_files = [%q{README.rdoc}, %q{bin/dme}, %q{lib/dnsmadeeasy/api.rb}, %q{lib/dnsmadeeasy/exceptions.rb}]
|
14
|
+
s.files = [%q{Manifest}, %q{README.rdoc}, %q{Rakefile}, %q{bin/dme}, %q{lib/dnsmadeeasy/api.rb}, %q{lib/dnsmadeeasy/exceptions.rb}, %q{dnsmadeeasy-api.gemspec}]
|
15
|
+
s.homepage = %q{http://rubygems.org/gems/dnsmadeeasy-api}
|
16
|
+
s.post_install_message = %q{Create /etc/dnsmadeeasy/api.keys and/or /etc/dnsmadeeasy/api_sandbox.keys with the following information
|
17
|
+
api_key=<your api key>
|
18
|
+
secret_key=<your secret key>
|
19
|
+
to use the dme binary.}
|
20
|
+
s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Dnsmadeeasy-api}, %q{--main}, %q{README.rdoc}]
|
21
|
+
s.require_paths = [%q{lib}]
|
22
|
+
s.rubyforge_project = %q{dnsmadeeasy-api}
|
23
|
+
s.rubygems_version = %q{1.8.5}
|
24
|
+
s.summary = %q{Ruby client for DNSMadeEasy API.}
|
25
|
+
|
26
|
+
if s.respond_to? :specification_version then
|
27
|
+
s.specification_version = 3
|
28
|
+
|
29
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
30
|
+
s.add_runtime_dependency(%q<rest-client>, [">= 0"])
|
31
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
32
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
33
|
+
s.add_development_dependency(%q<echoe>, [">= 0"])
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<rest-client>, [">= 0"])
|
36
|
+
s.add_dependency(%q<json>, [">= 0"])
|
37
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
38
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
39
|
+
end
|
40
|
+
else
|
41
|
+
s.add_dependency(%q<rest-client>, [">= 0"])
|
42
|
+
s.add_dependency(%q<json>, [">= 0"])
|
43
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
44
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,275 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "time"
|
3
|
+
require "openssl"
|
4
|
+
require "rest_client"
|
5
|
+
require "json"
|
6
|
+
require File.dirname(__FILE__)+"/exceptions"
|
7
|
+
|
8
|
+
=begin rdoc
|
9
|
+
= DnsMadeEasy/API
|
10
|
+
|
11
|
+
Ruby client for DNSMadeEasy API.
|
12
|
+
|
13
|
+
== Installation
|
14
|
+
|
15
|
+
# gem install environment
|
16
|
+
|
17
|
+
== Usage
|
18
|
+
|
19
|
+
require "rubygems"
|
20
|
+
require "dnsmadeeasy/api"
|
21
|
+
|
22
|
+
api_key = <your dnsmadeeasy api key>
|
23
|
+
secret_ket = <your dnsmadeeasy secret key>
|
24
|
+
api = DnsMadeEasy::Api(api_key, secret_key)
|
25
|
+
api.list_records "sigfig.com"
|
26
|
+
|
27
|
+
To run in sandbox mode (you need an account and api key at sandbox.dnsmadeeasy.com).
|
28
|
+
This is a great way to test your application without changing your production DNS entries.
|
29
|
+
|
30
|
+
api = DnsMadeEasy::Api(api_key, secret_key, true)
|
31
|
+
api.list_records "sigfig.com"
|
32
|
+
|
33
|
+
== Command line tool
|
34
|
+
|
35
|
+
The client comes with a command line tool "dme". Use "dme --help" to see how to use the command.
|
36
|
+
The command line tool requires that your api credentials be stored in /etc/dnsmadeeasy/api.keys as
|
37
|
+
api_key=<api_key>
|
38
|
+
secret_key=<secret_key>
|
39
|
+
|
40
|
+
The command line tool also allows the running of queries in the sandbox mode. To do so, create
|
41
|
+
/etc/dnsmadeeasy/api_sandbox.keys with your sandbox api key and secret key and use the --sandbox option
|
42
|
+
with every command.
|
43
|
+
|
44
|
+
=end
|
45
|
+
|
46
|
+
module DnsMadeEasy
|
47
|
+
TTL_ONE_HOUR = 3600
|
48
|
+
TTL_HALF_HOUR = 1800
|
49
|
+
TTL_FIVE_MINS = 300
|
50
|
+
TTL_ONE_DAY = 86400
|
51
|
+
TTL_ONE_WEEK = 604800
|
52
|
+
|
53
|
+
class Api
|
54
|
+
# Initialize the class with the api key, the secret key, and an optional
|
55
|
+
# flag to run the queries in DNSMadeEasy's sandbox mode
|
56
|
+
def initialize(api_key, secret_key, sandbox=false)
|
57
|
+
@api_key = api_key
|
58
|
+
@secret_key = secret_key
|
59
|
+
@sandbox = sandbox
|
60
|
+
end
|
61
|
+
|
62
|
+
# List all domains in the account.
|
63
|
+
# Returns an array of domain names in the account.
|
64
|
+
# Throws DnsMadeEasy::AuthorizationFailedError
|
65
|
+
def list_domains
|
66
|
+
begin
|
67
|
+
response = RestClient.get request_url, headers
|
68
|
+
response_hash = JSON.parse(response)
|
69
|
+
return response_hash.has_key?("list") ? response_hash["list"] : []
|
70
|
+
rescue RestClient::Forbidden => e
|
71
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Delete all domains in the account.
|
76
|
+
# Returns true or throws an exception.
|
77
|
+
# Throws DnsMadeEasy::AuthorizationFailedError
|
78
|
+
def delete_domains!
|
79
|
+
begin
|
80
|
+
response = RestClient.delete request_url, headers
|
81
|
+
return true
|
82
|
+
rescue RestClient::Forbidden => e
|
83
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Create a new domain entry.
|
88
|
+
# Returns a hash of the newly created domain entry.
|
89
|
+
# Throws DnsMadeEasy::InvalidDomainNameError, DnsMadeEasy::DuplicateDomainError, or DnsMadeEasy::AuthorizationFailedError
|
90
|
+
def create_domain!(domain)
|
91
|
+
begin
|
92
|
+
response = RestClient.put request_url(:path => "#{domain}"), {}, headers
|
93
|
+
return JSON.parse(response)
|
94
|
+
rescue RestClient::BadRequest => e
|
95
|
+
error = JSON.parse(e.http_body)
|
96
|
+
if error["error"][0] == "Invalid domain name."
|
97
|
+
raise DnsMadeEasy::InvalidDomainNameError, domain
|
98
|
+
else
|
99
|
+
raise DnsMadeEasy::DuplicateDomainError, domain
|
100
|
+
end
|
101
|
+
rescue RestClient::Forbidden => e
|
102
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Delete a domain entry.
|
107
|
+
# Returns true or throws an exception.
|
108
|
+
# Throws DnsMadeEasy::UnknownDomainError, DnsMadeEasy::RequestFailedError, or DnsMadeEasy::AuthorizationFailedError
|
109
|
+
def delete_domain!(domain)
|
110
|
+
begin
|
111
|
+
response = RestClient.delete request_url(:path => "#{domain}"), headers
|
112
|
+
return true
|
113
|
+
rescue RestClient::ResourceNotFound => e
|
114
|
+
raise DnsMadeEasy::UnknownDomainError, domain
|
115
|
+
rescue RestClient::BadRequest => e
|
116
|
+
error = JSON.parse(e.http_body)
|
117
|
+
raise DnsMadeEasy::RequestFailedError, error["error"][0]
|
118
|
+
rescue RestClient::Forbidden => e
|
119
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Describe a domain entry.
|
124
|
+
# Returns a hash of the domain entry.
|
125
|
+
# Throws DnsMadeEasy::UnknownDomainError or DnsMadeEasy::AuthorizationFailedError
|
126
|
+
def describe_domain(domain)
|
127
|
+
begin
|
128
|
+
response = RestClient.get request_url(:path => "#{domain}"), headers
|
129
|
+
return JSON.parse(response)
|
130
|
+
rescue RestClient::ResourceNotFound => e
|
131
|
+
raise DnsMadeEasy::UnknownDomainError, domain
|
132
|
+
rescue RestClient::Forbidden => e
|
133
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# List records for a domain.
|
138
|
+
# Returns an array of hashes, each hash representing a dns entry.
|
139
|
+
# Throws DnsMadeEasy::UnknownDomainError or DnsMadeEasy::AuthorizationFailedError
|
140
|
+
def list_records(domain, filter={})
|
141
|
+
begin
|
142
|
+
response = RestClient.get request_url(:path => "#{domain}/records", :query => filter), headers
|
143
|
+
return JSON.parse(response)
|
144
|
+
rescue RestClient::ResourceNotFound => e
|
145
|
+
raise DnsMadeEasy::UnknownDomainError, domain
|
146
|
+
rescue RestClient::Forbidden => e
|
147
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Create a new dns record
|
152
|
+
# record should be a hash with the following values:
|
153
|
+
#
|
154
|
+
# :name => hostname, e.g. www
|
155
|
+
# :type => e.g. :A, :CNAME, :MX, :TXT, :SRV, :NS, :AAAA, :HTTPRED, :PTR
|
156
|
+
# :data => publicname, e.g. "66.88.99.44" or "ec2-gibberish.amazonaws.com"
|
157
|
+
# :gtdLocation => "DEFAULT", (optional, defaults to DEFAULT)
|
158
|
+
# :ttl => time to live, e.g. 300
|
159
|
+
#
|
160
|
+
# for :CNAME record type, the domain name is automatically added to the entry unless
|
161
|
+
# the :data field ends in a .
|
162
|
+
# e.g., for domain sigfig.com,
|
163
|
+
# :data => "blog.google.com" for a cname entry resolves to blog.google.com.sigfig.com
|
164
|
+
# but :data => "blog.google.com." resolves to blog.google.com.
|
165
|
+
#
|
166
|
+
# Returns a hash of the newly created dns entry.
|
167
|
+
# Throws DnsMadeEasy::InvalidRecordError, DnsMadeEasy::UnknownDomainError, or DnsMadeEasy::AuthorizationFailedError
|
168
|
+
def create_record!(domain, record)
|
169
|
+
validate_record(record)
|
170
|
+
request_data = {
|
171
|
+
:gtdLocation => "DEFAULT"
|
172
|
+
}.merge(record)
|
173
|
+
begin
|
174
|
+
response = RestClient.post request_url(:path => "#{domain}/records"), request_data.to_json, headers(:content_type => "application/json")
|
175
|
+
return JSON.parse(response)
|
176
|
+
rescue RestClient::BadRequest => e
|
177
|
+
raise DnsMadeEasy::InvalidRecordError, e.http_body
|
178
|
+
rescue RestClient::ResourceNotFound => e
|
179
|
+
raise DnsMadeEasy::UnknownDomainError, domain
|
180
|
+
rescue RestClient::Forbidden => e
|
181
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Delete a dns record.
|
186
|
+
# Returns true or throws an exception.
|
187
|
+
# Throws DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
|
188
|
+
def delete_record!(domain, record_id)
|
189
|
+
begin
|
190
|
+
response = RestClient.delete request_url(:path => "#{domain}/records/#{record_id}"), headers
|
191
|
+
return true
|
192
|
+
rescue RestClient::ResourceNotFound => e
|
193
|
+
raise DnsMadeEasy::UnknownRecordError.new(domain, record_id)
|
194
|
+
rescue RestClient::Forbidden => e
|
195
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Update an existing dns record
|
200
|
+
# Returns the latest hash of the dns entry.
|
201
|
+
# Throws DnsMadeEasy::InvalidRecordError, DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
|
202
|
+
def update_record!(domain, record_id, record)
|
203
|
+
begin
|
204
|
+
response = RestClient.put request_url(:path => "#{domain}/records/#{record_id}"), record.to_json, headers(:content_type => "application/json")
|
205
|
+
return describe_record(domain, record_id)
|
206
|
+
rescue RestClient::BadRequest => e
|
207
|
+
raise DnsMadeEasy::InvalidRecordError, e.http_body
|
208
|
+
rescue RestClient::ResourceNotFound => e
|
209
|
+
raise DnsMadeEasy::UnknownRecordError.new(domain, record_id)
|
210
|
+
rescue RestClient::Forbidden => e
|
211
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
# Describe an existing dns record.
|
216
|
+
# Returns a hash of the dns entry.
|
217
|
+
# Throws DnsMadeEasy::UnknownRecordError, or DnsMadeEasy::AuthorizationFailedError
|
218
|
+
def describe_record(domain, record_id)
|
219
|
+
begin
|
220
|
+
response = RestClient.get request_url(:path => "#{domain}/records/#{record_id}"), headers
|
221
|
+
return JSON.parse(response)
|
222
|
+
rescue RestClient::ResourceNotFound => e
|
223
|
+
raise DnsMadeEasy::UnknownRecordError.new(domain, record_id)
|
224
|
+
rescue RestClient::Forbidden => e
|
225
|
+
raise DnsMadeEasy::AuthorizationFailedError
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
private
|
230
|
+
|
231
|
+
# Validate a dns record entry
|
232
|
+
def validate_record(record)
|
233
|
+
# check missing fields
|
234
|
+
required_fields = [:ttl, :data, :type, :name]
|
235
|
+
required_fields.each do |field|
|
236
|
+
raise DnsMadeEasy::InvalidRecordError, "Missing field #{field}" unless record.has_key?(field)
|
237
|
+
end
|
238
|
+
|
239
|
+
# check record types
|
240
|
+
acceptable_types = [:A, :CNAME, :MX, :TXT, :SRV, :NS, :AAAA, :HTTPRED, :PTR]
|
241
|
+
raise DnsMadeEasy::InvalidRecordError, "Invalid record type #{record[:type]}" unless acceptable_types.include?(record[:type])
|
242
|
+
|
243
|
+
# check non empty fields
|
244
|
+
non_empty_fields = [:ttl, :data]
|
245
|
+
non_empty_fields.each do |field|
|
246
|
+
raise DnsMadeEasy::InvalidRecordError, "Field #{field} cannot be empty" if record[:data].empty?
|
247
|
+
raise DnsMadeEasy::InvalidRecordError, "Field #{field} cannot be nil" if record[:data].nil?
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
# Create the api request url
|
252
|
+
def request_url(info={})
|
253
|
+
request_url = @sandbox ? "http://api.sandbox.dnsmadeeasy.com/V1.2/domains" : "http://api.dnsmadeeasy.com/V1.2/domains"
|
254
|
+
request_url = "#{request_url}/#{info[:path]}" if info.has_key?(:path)
|
255
|
+
if info.has_key?(:query) && !info[:query].empty?
|
256
|
+
query = info[:query].to_a.map { |x| "#{x[0]}=#{x[1]}" }.join("&")
|
257
|
+
request_url = "#{request_url}?#{query}"
|
258
|
+
end
|
259
|
+
return request_url
|
260
|
+
end
|
261
|
+
|
262
|
+
# Return the api request headers
|
263
|
+
def headers(more_headers={})
|
264
|
+
time_now = Time.now.httpdate
|
265
|
+
hmac = OpenSSL::HMAC.hexdigest('sha1', @secret_key, time_now)
|
266
|
+
default_headers = {
|
267
|
+
:"x-dnsme-hmac" => hmac,
|
268
|
+
:"x-dnsme-requestDate"=> time_now,
|
269
|
+
:"x-dnsme-apiKey" => @api_key,
|
270
|
+
:accept => "application/json"
|
271
|
+
}
|
272
|
+
return default_headers.merge( more_headers )
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module DnsMadeEasy
|
2
|
+
# Generic request failure error
|
3
|
+
class RequestFailedError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
# Error raised when authorization fails
|
7
|
+
class AuthorizationFailedError < RequestFailedError
|
8
|
+
def initialize
|
9
|
+
super "Could not authorize request with the given api key and secret key"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Error raised when actions are performed on an domain not listed in the account
|
14
|
+
class UnknownDomainError < RequestFailedError
|
15
|
+
def initialize(domain)
|
16
|
+
super "Domain #{domain} does not exist."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Error raised when an invalid domain is being created
|
21
|
+
class InvalidDomainNameError < RequestFailedError
|
22
|
+
def initialize(domain)
|
23
|
+
super "Domain #{domain} is not valid."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Error raised when a duplicate domain is being created
|
28
|
+
class DuplicateDomainError < RequestFailedError
|
29
|
+
def initialize(domain)
|
30
|
+
super "Domain #{domain} already exists."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Error raised when an unknown record is being modified or deleted
|
35
|
+
class UnknownRecordError < RequestFailedError
|
36
|
+
def initialize(domain, record_id)
|
37
|
+
super "Record id #{record_id} and/or domain #{domain} does not exist"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Error raised when an invalid dns entry is being created
|
42
|
+
class InvalidRecordError < RequestFailedError
|
43
|
+
end
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dnsmadeeasy-api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 9
|
9
|
+
version: "0.9"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Nitesh Goel
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-07-06 00:00:00 Z
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
20
|
+
name: rest-client
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: json
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
hash: 3
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
version: "0"
|
45
|
+
type: :runtime
|
46
|
+
version_requirements: *id002
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
prerelease: false
|
50
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
type: :development
|
60
|
+
version_requirements: *id003
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: echoe
|
63
|
+
prerelease: false
|
64
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
type: :development
|
74
|
+
version_requirements: *id004
|
75
|
+
description: Ruby client for DNSMadeEasy API.
|
76
|
+
email: nitesh@wikinvest.com
|
77
|
+
executables:
|
78
|
+
- dme
|
79
|
+
extensions: []
|
80
|
+
|
81
|
+
extra_rdoc_files:
|
82
|
+
- README.rdoc
|
83
|
+
- bin/dme
|
84
|
+
- lib/dnsmadeeasy/api.rb
|
85
|
+
- lib/dnsmadeeasy/exceptions.rb
|
86
|
+
files:
|
87
|
+
- Manifest
|
88
|
+
- README.rdoc
|
89
|
+
- Rakefile
|
90
|
+
- bin/dme
|
91
|
+
- lib/dnsmadeeasy/api.rb
|
92
|
+
- lib/dnsmadeeasy/exceptions.rb
|
93
|
+
- dnsmadeeasy-api.gemspec
|
94
|
+
homepage: http://rubygems.org/gems/dnsmadeeasy-api
|
95
|
+
licenses: []
|
96
|
+
|
97
|
+
post_install_message: |-
|
98
|
+
Create /etc/dnsmadeeasy/api.keys and/or /etc/dnsmadeeasy/api_sandbox.keys with the following information
|
99
|
+
api_key=<your api key>
|
100
|
+
secret_key=<your secret key>
|
101
|
+
to use the dme binary.
|
102
|
+
rdoc_options:
|
103
|
+
- --line-numbers
|
104
|
+
- --inline-source
|
105
|
+
- --title
|
106
|
+
- Dnsmadeeasy-api
|
107
|
+
- --main
|
108
|
+
- README.rdoc
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
hash: 3
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
hash: 11
|
126
|
+
segments:
|
127
|
+
- 1
|
128
|
+
- 2
|
129
|
+
version: "1.2"
|
130
|
+
requirements: []
|
131
|
+
|
132
|
+
rubyforge_project: dnsmadeeasy-api
|
133
|
+
rubygems_version: 1.8.5
|
134
|
+
signing_key:
|
135
|
+
specification_version: 3
|
136
|
+
summary: Ruby client for DNSMadeEasy API.
|
137
|
+
test_files: []
|
138
|
+
|