dnsmadeeasy-api 0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ Manifest
2
+ README.rdoc
3
+ Rakefile
4
+ bin/dme
5
+ lib/dnsmadeeasy/api.rb
6
+ lib/dnsmadeeasy/exceptions.rb
@@ -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
@@ -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
+