registrar-client 0.1.0
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/LICENSE +19 -0
- data/Readme.md +70 -0
- data/Spec.md +55 -0
- data/examples/enom.example.yml +4 -0
- data/examples/purchase_com.rb +7 -0
- data/lib/registrar-client.rb +1 -0
- data/lib/registrar.rb +14 -0
- data/lib/registrar/client.rb +224 -0
- data/lib/registrar/contact.rb +31 -0
- data/lib/registrar/domain.rb +26 -0
- data/lib/registrar/extended_attribute.rb +12 -0
- data/lib/registrar/extended_attribute_descriptor.rb +31 -0
- data/lib/registrar/extended_attribute_option_descriptor.rb +7 -0
- data/lib/registrar/name_server.rb +16 -0
- data/lib/registrar/order.rb +43 -0
- data/lib/registrar/provider/enom.rb +430 -0
- data/lib/registrar/provider/enom/contact.rb +68 -0
- data/lib/registrar/provider/enom/extended_attribute.rb +64 -0
- data/lib/registrar/provider/enom/extended_attribute_be.rb +0 -0
- data/lib/registrar/provider/enom/extended_attribute_ca.rb +40 -0
- data/lib/registrar/provider/enom/extended_attribute_io.rb +18 -0
- data/lib/registrar/provider/enom/extended_attribute_us.rb +29 -0
- data/lib/registrar/provider/enom/order.rb +41 -0
- data/lib/registrar/provider/opensrs.rb +133 -0
- data/lib/registrar/provider/opensrs/contact.rb +30 -0
- data/lib/registrar/provider/opensrs/contact_set.rb +24 -0
- data/lib/registrar/provider/opensrs/name_server_list.rb +26 -0
- data/lib/registrar/provider/opensrs/operation.rb +42 -0
- data/lib/registrar/provider/opensrs/order.rb +59 -0
- data/lib/registrar/provider/opensrs/tld_data.rb +29 -0
- data/lib/registrar/provider/opensrs/tld_data_us.rb +48 -0
- data/lib/registrar/purchase_options.rb +29 -0
- data/lib/registrar/renewal_options.rb +8 -0
- metadata +177 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2011 by Anthony Eden
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/Readme.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Registrar Client
|
2
|
+
|
3
|
+
This library provides a common API for communicating with multiple registrars. This is necessary since different registrars support different TLDs and different add-on services.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
To construct a client, first require both the generic API interface as well as a specific provider. Construct the provider and pass it to the client interface:
|
8
|
+
|
9
|
+
require 'registrar'
|
10
|
+
require 'registrar/provider/enom'
|
11
|
+
|
12
|
+
# set url, username and password to Enom API endpoint, username and password respectively
|
13
|
+
provider = Registrar::Provider::Enom.new(url, username, password)
|
14
|
+
client = Registrar::Client.new(provider)
|
15
|
+
|
16
|
+
To split a domain into its TLD and its remaining part:
|
17
|
+
|
18
|
+
name = 'example.com'
|
19
|
+
client.parse(name)
|
20
|
+
=> ['example','com']
|
21
|
+
|
22
|
+
To check the availability of a domain name for registration:
|
23
|
+
|
24
|
+
client.available?(name)
|
25
|
+
=> true
|
26
|
+
|
27
|
+
To register a domain name, first construct contact:
|
28
|
+
|
29
|
+
registrant = Registrar::Contact.new(
|
30
|
+
:first_name => 'Anthony',
|
31
|
+
:last_name => 'Eden',
|
32
|
+
:address_1 => '123 SW 1st Street',
|
33
|
+
:city => 'Anywhere',
|
34
|
+
:country => 'US',
|
35
|
+
:postal_code => '12121',
|
36
|
+
:phone => '444 555 1212',
|
37
|
+
:email => 'anthony@dnsimple.com'
|
38
|
+
)
|
39
|
+
|
40
|
+
Next pass the name plus the contact (as the registrant) to the purchase method:
|
41
|
+
|
42
|
+
order = client.purchase(name, registrant)
|
43
|
+
|
44
|
+
The resulting order may be complete...
|
45
|
+
|
46
|
+
domains = order.domains if order.complete?
|
47
|
+
=> [#<Registrar::Domain:0x10034d298>]
|
48
|
+
domain = domains[0]
|
49
|
+
=>
|
50
|
+
domain.name
|
51
|
+
=> "example.com"
|
52
|
+
|
53
|
+
Or the resulting order may be in process...
|
54
|
+
|
55
|
+
order.status unless order.complete?
|
56
|
+
=> :open
|
57
|
+
|
58
|
+
The status of the domain may be open in cases where a domain is not registered in real-time. Quite often country-code top level domains are not real-time and require additional out-of-band processing and documentation.
|
59
|
+
|
60
|
+
If you need to pass in additional purchase options:
|
61
|
+
|
62
|
+
purchase_options = Registrar::PurchaseOptions.new
|
63
|
+
purchase_options.name_servers << Registrar::NameServer.new('ns1.example.com')
|
64
|
+
purchase_options.name_servers << Registrar::NameServer.new('ns2.example.com')
|
65
|
+
purchase_options.extended_attributes << Registrar::ExtendedAttribute.new('name', 'value')
|
66
|
+
purchase_options.number_of_years = 2
|
67
|
+
|
68
|
+
order = client.purchase(name, registrant, purchase_options)
|
69
|
+
domain = order.domain
|
70
|
+
=> #<Registrar::Domain:"example.com">
|
data/Spec.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
domain.name_servers
|
13
|
+
=> [#<Registrar::NameServer:"ns1.example.com">, #<Registrar::Domain:"ns2.example.com">]
|
14
|
+
|
15
|
+
To find an already purchased domain by its name so you can get more details:
|
16
|
+
|
17
|
+
domain = client.find('example.com')
|
18
|
+
=> #<Registrar::Domain:"example.com">
|
19
|
+
|
20
|
+
To transfer a domain
|
21
|
+
|
22
|
+
transfer_order = client.transfer(name, registrant)
|
23
|
+
|
24
|
+
Or, with purchase options:
|
25
|
+
|
26
|
+
transfer_options = Registrar::TransferOptions.new
|
27
|
+
purchase_options.name_servers << Registrar::NameServer.new('ns1.example.com')
|
28
|
+
purchase_options.name_servers << Registrar::NameServer.new('ns2.example.com')
|
29
|
+
purchase_options.extended_attributes << Registrar::ExtendedAttribute.new('name', 'value')
|
30
|
+
transfer_order = client.transfer(name, registrant, transfer_options)
|
31
|
+
|
32
|
+
To renew a domain:
|
33
|
+
|
34
|
+
domain.expires_on
|
35
|
+
=> '2011-03-04'
|
36
|
+
domain.renew
|
37
|
+
=> true
|
38
|
+
domain.expires_on
|
39
|
+
=> '2012-03-04'
|
40
|
+
|
41
|
+
To delete a registration (this will not refund):
|
42
|
+
|
43
|
+
ip_address = '1.2.3.4'
|
44
|
+
domain.delete(ip_address)
|
45
|
+
=> true
|
46
|
+
|
47
|
+
To get a list of supported TLDs along with properties:
|
48
|
+
|
49
|
+
tld = client.tlds.first
|
50
|
+
tld.name
|
51
|
+
=> "com"
|
52
|
+
tld.max_years
|
53
|
+
=> 10
|
54
|
+
|
55
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'registrar'
|
2
|
+
require 'registrar/provider/enom'
|
3
|
+
config = YAML.load_file('examples/enom.yml')
|
4
|
+
provider = Registrar::Provider::Enom.new(config['url'], config['username'], config['password'])
|
5
|
+
contact = Registrar::Contact.new(:first_name => "John", :last_name => "Doe")
|
6
|
+
name = "test-domain-#{Time.now.to_i}-#{rand(10000)}.com"
|
7
|
+
order = provider.purchase(name, contact)
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'registrar'
|
data/lib/registrar.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module Registrar
|
4
|
+
# Error indicating that a registrar provider is required but none was
|
5
|
+
# available.
|
6
|
+
class ProviderRequiredError < RuntimeError
|
7
|
+
end
|
8
|
+
|
9
|
+
# Base error for any errors encountered while communicating with a registrar.
|
10
|
+
class RegistrarError < RuntimeError
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'registrar/client'
|
@@ -0,0 +1,224 @@
|
|
1
|
+
require 'registrar/contact'
|
2
|
+
require 'registrar/domain'
|
3
|
+
require 'registrar/purchase_options'
|
4
|
+
require 'registrar/renewal_options'
|
5
|
+
require 'registrar/extended_attribute_descriptor'
|
6
|
+
require 'registrar/extended_attribute_option_descriptor'
|
7
|
+
require 'registrar/extended_attribute'
|
8
|
+
require 'registrar/name_server'
|
9
|
+
require 'registrar/order'
|
10
|
+
|
11
|
+
module Registrar #:nodoc:
|
12
|
+
# This class provides a generic client interface for accessing domain
|
13
|
+
# registrars as a domain reseller. The interface provides methods for
|
14
|
+
# checking domain availability, registering domain names and finding
|
15
|
+
# details on domains that are already registered.
|
16
|
+
#
|
17
|
+
# For examples of how to use this interface please see README.textile.
|
18
|
+
class Client
|
19
|
+
attr_reader :provider
|
20
|
+
|
21
|
+
# Initialize the client with an provider.
|
22
|
+
#
|
23
|
+
# adapter - The provider instance.
|
24
|
+
def initialize(provider)
|
25
|
+
@provider = provider
|
26
|
+
end
|
27
|
+
|
28
|
+
# Parse a domain name into it's top-level domain part and its remaining
|
29
|
+
# parts.
|
30
|
+
#
|
31
|
+
# name - The fully-qualified domain name to parse
|
32
|
+
#
|
33
|
+
# Returns an array with two elements. The first element is a string with
|
34
|
+
# all parts of the domain minus the TLD. The last element is the TLD
|
35
|
+
# string.
|
36
|
+
def parse(name)
|
37
|
+
name = name.downcase
|
38
|
+
parse_cache[name] ||= provider.parse(name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def parse_cache
|
42
|
+
@parse_cache ||= {}
|
43
|
+
end
|
44
|
+
private :parse_cache
|
45
|
+
|
46
|
+
# Check for the availability of a domain.
|
47
|
+
#
|
48
|
+
# name - The fully-qualified domain name to check.
|
49
|
+
#
|
50
|
+
# Returns true if the name is available.
|
51
|
+
def available?(name)
|
52
|
+
provider.available?(name.downcase)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Find a domain and return an object representing that domain.
|
56
|
+
# If the domain is not registered or is registered with another reseller then
|
57
|
+
# this method will return nil.
|
58
|
+
#
|
59
|
+
# name - The fully-qualified domain name.
|
60
|
+
#
|
61
|
+
# Returns a Registrar::Domain object.
|
62
|
+
def find(name)
|
63
|
+
provider.find(name.downcase)
|
64
|
+
end
|
65
|
+
alias :find_domain :find
|
66
|
+
|
67
|
+
# Get a set of extended attribute descriptor objects. This set can be
|
68
|
+
# used to determine what extended registry attributes must be collected
|
69
|
+
# for the given domain.
|
70
|
+
#
|
71
|
+
# name - The fully-qualified domain name.
|
72
|
+
#
|
73
|
+
# Returns an array of Registrar::ExtendedAttribute objects.
|
74
|
+
def extended_attributes(name)
|
75
|
+
provider.extended_attributes(name)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Purchase a domain name for the given registrant.
|
79
|
+
#
|
80
|
+
# name - The fully-qualified domain name to purchase.
|
81
|
+
# registrant - A complete Registrar::Contact instance.
|
82
|
+
# registration_options - Optional Registrar::RegistrationOptions instance.
|
83
|
+
#
|
84
|
+
# Returns a Registrar::Order
|
85
|
+
def purchase(name, registrant, registration_options=nil)
|
86
|
+
provider.purchase(name.downcase, registrant, registration_options)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Get the order identified by the given ID
|
90
|
+
#
|
91
|
+
# id - The order ID
|
92
|
+
#
|
93
|
+
# Returns a Registrar::Order
|
94
|
+
def order(id)
|
95
|
+
provider.order(id)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Get the most recent order for the given name
|
99
|
+
#
|
100
|
+
# name - The fully-qualified domain name
|
101
|
+
#
|
102
|
+
# Returns a Registrar::Order instance
|
103
|
+
def order_for_domain(name)
|
104
|
+
provider.order_for_domain(name)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Renew a domain name.
|
108
|
+
#
|
109
|
+
# name - The fully-qualified domain name to renew.
|
110
|
+
# renewal_options - Optional Registrar::RenewalOptions instance.
|
111
|
+
#
|
112
|
+
# Returns a Registrar::Order
|
113
|
+
def renew(name, renewal_options=nil)
|
114
|
+
provider.renew(name.downcase, renewal_options)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Return true if the domain is set up for auto renewal
|
118
|
+
#
|
119
|
+
# name - The fully-qualified domain name
|
120
|
+
#
|
121
|
+
# Returns true if the domain should be auto renewed by the registrar
|
122
|
+
def auto_renew?(name)
|
123
|
+
provider.auto_renew?(name)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Enable auto-renewal for a domain
|
127
|
+
#
|
128
|
+
# name - The name to auto renew
|
129
|
+
#
|
130
|
+
# Returns true of auto-renewal was enabled
|
131
|
+
def enable_auto_renewal(name)
|
132
|
+
provider.enable_auto_renewal(name)
|
133
|
+
end
|
134
|
+
alias :enable_auto_renew :enable_auto_renewal
|
135
|
+
|
136
|
+
# Disable auto-renewal for a domain
|
137
|
+
#
|
138
|
+
# name - The name that has auto renewal enabled
|
139
|
+
#
|
140
|
+
# Returns true if the auto-renewal was disabled
|
141
|
+
def disable_auto_renewal(name)
|
142
|
+
provider.disable_auto_renewal(name)
|
143
|
+
end
|
144
|
+
alias :disable_auto_renew :disable_auto_renewal
|
145
|
+
|
146
|
+
# List name servers for a domain.
|
147
|
+
#
|
148
|
+
# name - The fully-qualified domain name.
|
149
|
+
#
|
150
|
+
# Returns a list of name servers attached to this domain
|
151
|
+
def name_servers(name)
|
152
|
+
provider.name_servers(name.downcase)
|
153
|
+
end
|
154
|
+
alias :nameservers :name_servers
|
155
|
+
|
156
|
+
# Set the name servers for a given name.
|
157
|
+
#
|
158
|
+
# name - The fully-qualified domain name.
|
159
|
+
# name_servers - A set of name server names as strings.
|
160
|
+
#
|
161
|
+
# Returns the list of name servers
|
162
|
+
def set_name_servers(name, name_servers=[])
|
163
|
+
provider.set_name_servers(name, name_servers)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Find a name server by name.
|
167
|
+
#
|
168
|
+
# name - The name server name
|
169
|
+
#
|
170
|
+
# Returns a Registrar::NameServer instance
|
171
|
+
def find_name_server(name)
|
172
|
+
provider.find_name_server(name)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Registers a name server with various registries
|
176
|
+
#
|
177
|
+
# name_server - The NameServer to register, including IP address
|
178
|
+
def register_name_server(name_server)
|
179
|
+
provider.register_name_server(name_server)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Return the minimum number of years required to register a domain.
|
183
|
+
#
|
184
|
+
# tld - The TLD.
|
185
|
+
#
|
186
|
+
# Returns the minimum number of years required for registration.
|
187
|
+
def minimum_number_of_years(tld)
|
188
|
+
provider.minimum_number_of_years(tld.downcase)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Return the retail transfer price for the given TLD.
|
192
|
+
#
|
193
|
+
# tld - The TLD.
|
194
|
+
#
|
195
|
+
# Returns the transfer price.
|
196
|
+
def tld_retail_transfer_price(tld)
|
197
|
+
provider.tld_retail_transfer_price(tld)
|
198
|
+
end
|
199
|
+
|
200
|
+
def contacts(name)
|
201
|
+
provider.contacts(name)
|
202
|
+
end
|
203
|
+
|
204
|
+
def update_registrant(name, contact)
|
205
|
+
provider.update_registrant(name, contact)
|
206
|
+
end
|
207
|
+
|
208
|
+
def update_contacts(name, contact)
|
209
|
+
provider.update_contacts(name, contact)
|
210
|
+
end
|
211
|
+
|
212
|
+
def update_technical_contact(name, contact)
|
213
|
+
provider.update_technical_contact(name, contact)
|
214
|
+
end
|
215
|
+
|
216
|
+
def update_administrative_contact(name, contact)
|
217
|
+
provider.update_administrative_contact(name, contact)
|
218
|
+
end
|
219
|
+
|
220
|
+
def update_aux_billing_contact(name, contact)
|
221
|
+
provider.update_aux_billing_contact(name, contact)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Registrar
|
2
|
+
class Contact
|
3
|
+
attr_accessor :identifier
|
4
|
+
attr_accessor :first_name
|
5
|
+
attr_accessor :last_name
|
6
|
+
attr_accessor :address_1
|
7
|
+
attr_accessor :address_2
|
8
|
+
attr_accessor :city
|
9
|
+
attr_accessor :state_province
|
10
|
+
attr_accessor :state_province_choice
|
11
|
+
attr_accessor :country
|
12
|
+
attr_accessor :postal_code
|
13
|
+
attr_accessor :phone
|
14
|
+
attr_accessor :phone_ext
|
15
|
+
attr_accessor :fax
|
16
|
+
attr_accessor :email
|
17
|
+
attr_accessor :organization_name
|
18
|
+
attr_accessor :job_title
|
19
|
+
|
20
|
+
# Create a new contact optionally providing a Hash with name/value pairs
|
21
|
+
# representing one or more of the contact attributes.
|
22
|
+
def initialize(attributes={})
|
23
|
+
attributes.each do |k, v|
|
24
|
+
m = "#{k}="
|
25
|
+
if respond_to?(m)
|
26
|
+
send(m, v)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Registrar
|
2
|
+
class Domain
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
attr_accessor :registrant
|
6
|
+
attr_accessor :order
|
7
|
+
|
8
|
+
attr_accessor :expiration
|
9
|
+
attr_accessor :registration_status
|
10
|
+
|
11
|
+
attr_accessor :lockable
|
12
|
+
attr_accessor :real_time
|
13
|
+
|
14
|
+
def initialize(name)
|
15
|
+
@name = name
|
16
|
+
end
|
17
|
+
|
18
|
+
def lockable?
|
19
|
+
!!lockable
|
20
|
+
end
|
21
|
+
|
22
|
+
def real_time?
|
23
|
+
!!real_time
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|