gandi_v5 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.rspec +3 -0
- data/.rubocop.yml +20 -0
- data/.travis.yml +23 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +6 -0
- data/Guardfile +40 -0
- data/LICENSE.md +32 -0
- data/README.md +94 -0
- data/Rakefile +3 -0
- data/TODO.md +29 -0
- data/bin/console +13 -0
- data/gandi_v5.gemspec +41 -0
- data/lib/gandi_v5/billing/info/prepaid.rb +33 -0
- data/lib/gandi_v5/billing/info.rb +26 -0
- data/lib/gandi_v5/billing.rb +28 -0
- data/lib/gandi_v5/data/converter/array_of.rb +35 -0
- data/lib/gandi_v5/data/converter/symbol.rb +26 -0
- data/lib/gandi_v5/data/converter/time.rb +28 -0
- data/lib/gandi_v5/data/converter.rb +41 -0
- data/lib/gandi_v5/data.rb +244 -0
- data/lib/gandi_v5/domain/auto_renew.rb +64 -0
- data/lib/gandi_v5/domain/contact.rb +102 -0
- data/lib/gandi_v5/domain/contract.rb +22 -0
- data/lib/gandi_v5/domain/dates.rb +44 -0
- data/lib/gandi_v5/domain/renewal_information.rb +41 -0
- data/lib/gandi_v5/domain/restore_information.rb +18 -0
- data/lib/gandi_v5/domain/sharing_space.rb +21 -0
- data/lib/gandi_v5/domain.rb +431 -0
- data/lib/gandi_v5/email/mailbox/responder.rb +36 -0
- data/lib/gandi_v5/email/mailbox.rb +236 -0
- data/lib/gandi_v5/email/offer.rb +27 -0
- data/lib/gandi_v5/email/slot.rb +134 -0
- data/lib/gandi_v5/email.rb +11 -0
- data/lib/gandi_v5/error/gandi_error.rb +21 -0
- data/lib/gandi_v5/error.rb +9 -0
- data/lib/gandi_v5/live_dns/domain.rb +211 -0
- data/lib/gandi_v5/live_dns/record_set.rb +79 -0
- data/lib/gandi_v5/live_dns/zone/snapshot.rb +62 -0
- data/lib/gandi_v5/live_dns/zone.rb +301 -0
- data/lib/gandi_v5/live_dns.rb +30 -0
- data/lib/gandi_v5/organization.rb +66 -0
- data/lib/gandi_v5/version.rb +5 -0
- data/lib/gandi_v5.rb +178 -0
- data/spec/.rubocop.yml +4 -0
- data/spec/features/domain_spec.rb +45 -0
- data/spec/features/livedns_domain_spec.rb +8 -0
- data/spec/features/livedns_zone_spec.rb +45 -0
- data/spec/features/mailbox_spec.rb +18 -0
- data/spec/fixtures/bodies/GandiV5_Billing/info.yaml +10 -0
- data/spec/fixtures/bodies/GandiV5_Domain/availability.yaml +15 -0
- data/spec/fixtures/bodies/GandiV5_Domain/fetch_contacts.yaml +8 -0
- data/spec/fixtures/bodies/GandiV5_Domain/get.yaml +37 -0
- data/spec/fixtures/bodies/GandiV5_Domain/list.yaml +20 -0
- data/spec/fixtures/bodies/GandiV5_Domain/renewal_info.yaml +12 -0
- data/spec/fixtures/bodies/GandiV5_Domain/restore_info.yaml +5 -0
- data/spec/fixtures/bodies/GandiV5_Domain/tld.yaml +10 -0
- data/spec/fixtures/bodies/GandiV5_Domain/tlds.yaml +7 -0
- data/spec/fixtures/bodies/GandiV5_Email_Mailbox/get.yaml +16 -0
- data/spec/fixtures/bodies/GandiV5_Email_Mailbox/list.yaml +8 -0
- data/spec/fixtures/bodies/GandiV5_Email_Slot/get.yaml +10 -0
- data/spec/fixtures/bodies/GandiV5_Email_Slot/list.yaml +8 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/get.yaml +4 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/list.yaml +2 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/get.yaml +11 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/list.yaml +11 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/get.yaml +9 -0
- data/spec/fixtures/bodies/GandiV5_Organization/get.yaml +17 -0
- data/spec/fixtures/vcr/Domain_features/List_domains.yml +54 -0
- data/spec/fixtures/vcr/Domain_features/Renew_domain.yml +133 -0
- data/spec/fixtures/vcr/LiveDNS_Domain_features/List_domains.yml +32 -0
- data/spec/fixtures/vcr/LiveDNS_Zone_features/List_zones.yml +42 -0
- data/spec/fixtures/vcr/LiveDNS_Zone_features/Make_and_save_snapshot.yml +72 -0
- data/spec/fixtures/vcr/LiveDNS_Zone_features/Save_zone_to_file.yml +28 -0
- data/spec/fixtures/vcr/Mailbox_features/List_mailboxes.yml +39 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/test.env +1 -0
- data/spec/units/gandi_v5/billing/info/prepaid_spec.rb +20 -0
- data/spec/units/gandi_v5/billing/info_spec.rb +4 -0
- data/spec/units/gandi_v5/billing_spec.rb +41 -0
- data/spec/units/gandi_v5/data/converter/array_of_spec.rb +18 -0
- data/spec/units/gandi_v5/data/converter/symbol_spec.rb +16 -0
- data/spec/units/gandi_v5/data/converter/time_spec.rb +16 -0
- data/spec/units/gandi_v5/data/converter_spec.rb +31 -0
- data/spec/units/gandi_v5/data_spec.rb +340 -0
- data/spec/units/gandi_v5/domain/auto_renew_spec.rb +70 -0
- data/spec/units/gandi_v5/domain/contact_spec.rb +36 -0
- data/spec/units/gandi_v5/domain/contract_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/dates_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/renewal_information_spec.rb +81 -0
- data/spec/units/gandi_v5/domain/restore_information_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/sharing_space_spec.rb +4 -0
- data/spec/units/gandi_v5/domain_spec.rb +451 -0
- data/spec/units/gandi_v5/email/mailbox/responder_spec.rb +131 -0
- data/spec/units/gandi_v5/email/mailbox_spec.rb +384 -0
- data/spec/units/gandi_v5/email/offer_spec.rb +17 -0
- data/spec/units/gandi_v5/email/slot_spec.rb +102 -0
- data/spec/units/gandi_v5/error/gandi_error_spec.rb +30 -0
- data/spec/units/gandi_v5/error_spec.rb +4 -0
- data/spec/units/gandi_v5/live_dns/domain_spec.rb +247 -0
- data/spec/units/gandi_v5/live_dns/record_set_spec.rb +74 -0
- data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +37 -0
- data/spec/units/gandi_v5/live_dns/zone_spec.rb +329 -0
- data/spec/units/gandi_v5/live_dns_spec.rb +17 -0
- data/spec/units/gandi_v5/organization_spec.rb +30 -0
- data/spec/units/gandi_v5_spec.rb +204 -0
- metadata +406 -0
@@ -0,0 +1,431 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# TODO: Add method renewal_price(currency: 'GBP', period: 1, sharing_id: self.sharing_id)
|
4
|
+
|
5
|
+
# TODO: Glue Record Management
|
6
|
+
# * get-v5-domain-domains-domain-hosts
|
7
|
+
# * post-v5-domain-domains-domain-hosts
|
8
|
+
# TODO: Glue Record Information
|
9
|
+
# * get-v5-domain-domains-domain-hosts-name
|
10
|
+
# * put-v5-domain-domains-domain-hosts-name
|
11
|
+
# * delete-v5-domain-domains-domain-hosts-name
|
12
|
+
# TODO: LiveDNS Management
|
13
|
+
# * get-v5-domain-domains-domain-livedns
|
14
|
+
# * post-v5-domain-domains-domain-livedns
|
15
|
+
# TODO: Nameservers Management
|
16
|
+
# * get-v5-domain-domains-domain-nameservers
|
17
|
+
# * put-v5-domain-domains-domain-nameservers
|
18
|
+
|
19
|
+
require_relative 'domain/auto_renew'
|
20
|
+
require_relative 'domain/contact'
|
21
|
+
require_relative 'domain/contract'
|
22
|
+
require_relative 'domain/dates'
|
23
|
+
require_relative 'domain/renewal_information'
|
24
|
+
require_relative 'domain/restore_information'
|
25
|
+
require_relative 'domain/sharing_space'
|
26
|
+
|
27
|
+
class GandiV5
|
28
|
+
# Gandi Domain Management API.
|
29
|
+
# @see https://api.gandi.net/docs/domains
|
30
|
+
# @!attribute [r] fqdn
|
31
|
+
# @return [String] fully qualified domain name, written in its native alphabet (IDN).
|
32
|
+
# @!attribute [r] fqdn_unicode
|
33
|
+
# @return [String] fully qualified domain name, written in unicode.
|
34
|
+
# @see https://docs.gandi.net/en/domain_names/register/idn.html
|
35
|
+
# @!attribute [r] name_servers
|
36
|
+
# @return [Array<String>]
|
37
|
+
# @!attribute [r] services
|
38
|
+
# @return [Array<Symbol>] list of Gandi services attached to this domain.
|
39
|
+
# gandidns, redirection, gandimail, packmail, dnssec, blog, hosting,
|
40
|
+
# paas, site, certificate, gandilivedns, mailboxv2
|
41
|
+
# @!attribute [r] sharing_space
|
42
|
+
# @return [GandiV5::Domain::SharingSpace]
|
43
|
+
# @!attribute [r] status
|
44
|
+
# @return [String] one of: "clientHold", "clientUpdateProhibited", "clientTransferProhibited",
|
45
|
+
# "clientDeleteProhibited", "clientRenewProhibited", "serverHold", "pendingTransfer",
|
46
|
+
# "serverTransferProhibited"
|
47
|
+
# @see https://docs.gandi.net/en/domain_names/faq/domain_statuses.html
|
48
|
+
# @!attribute [r] tld
|
49
|
+
# @return [String]
|
50
|
+
# @!attribute [r] dates
|
51
|
+
# @return [GandiV5::Domain::Dates]
|
52
|
+
# @!attribute [r] can_tld_lock
|
53
|
+
# @return [Boolean]
|
54
|
+
# @!attribute [r] contacts
|
55
|
+
# @return [Hash<:owner, :admin, :bill, :tech => GandiV5::Domain::Contact>]
|
56
|
+
# @!attribute [r] auto_renew
|
57
|
+
# @return [GandiV5::Domain::AutoRenew]
|
58
|
+
# @!attribute [r] auth_info
|
59
|
+
# @return [nil, String]
|
60
|
+
# @!attribute [r] uuid
|
61
|
+
# @return [nil, String]
|
62
|
+
# @!attribute [r] sharing_uuid
|
63
|
+
# @return [nil, String]
|
64
|
+
# @!attribute [r] tags
|
65
|
+
# @return [nil, Array<String>] list of tags that have been assigned to the domain.
|
66
|
+
# @!attribute [r] trustee_roles
|
67
|
+
# @return [nil, Array<Symbol>] one of: admin, tech.
|
68
|
+
# @!attribute [r] owner
|
69
|
+
# @return [String]
|
70
|
+
# @!attribute [r] organisation_owner
|
71
|
+
# @return [_String
|
72
|
+
# @!attribute [r] domain_owner
|
73
|
+
# @return [String]
|
74
|
+
# @!attribute [r] name_server
|
75
|
+
# @return [Symbol]
|
76
|
+
class Domain
|
77
|
+
include GandiV5::Data
|
78
|
+
|
79
|
+
SERVICES = {
|
80
|
+
gandidns: 'GandiDNS',
|
81
|
+
gandilivedns: 'LiveDNS',
|
82
|
+
dnssec: 'DNSSEC',
|
83
|
+
certificate: 'SSL Certificate',
|
84
|
+
paas: 'PAAS',
|
85
|
+
redirection: 'Redirection',
|
86
|
+
gandimail: 'GandiMail',
|
87
|
+
packmail: 'PackMail',
|
88
|
+
blog: 'Blog',
|
89
|
+
hosting: 'Hosting',
|
90
|
+
site: 'Site',
|
91
|
+
mailboxv2: 'MailboxV2'
|
92
|
+
}.freeze
|
93
|
+
|
94
|
+
STATUSES = {
|
95
|
+
clientHold: 'clientHold',
|
96
|
+
clientUpdateProhibited: 'clientUpdateProhibited',
|
97
|
+
clientTransferProhibited: 'clientTransferProhibited',
|
98
|
+
clientDeleteProhibited: 'clientDeleteProhibited',
|
99
|
+
clientRenewProhibited: 'clientRenewProhibited',
|
100
|
+
serverHold: 'serverHold',
|
101
|
+
pendingTransfer: 'pendingTransfer',
|
102
|
+
serverTransferProhibited: 'serverTransferProhibited'
|
103
|
+
}.freeze
|
104
|
+
|
105
|
+
CONTACTS_CONVERTER = lambda { |hash|
|
106
|
+
break {} if hash.nil?
|
107
|
+
|
108
|
+
hash = hash.transform_keys(&:to_sym)
|
109
|
+
.transform_values { |value| GandiV5::Domain::Contact.from_gandi value }
|
110
|
+
|
111
|
+
hash.define_singleton_method(:owner) { send :'[]', :owner }
|
112
|
+
hash.define_singleton_method(:admin) { send :'[]', :admin }
|
113
|
+
hash.define_singleton_method(:bill) { send :'[]', :bill }
|
114
|
+
hash.define_singleton_method(:tech) { send :'[]', :tech }
|
115
|
+
|
116
|
+
hash
|
117
|
+
}
|
118
|
+
private_constant :CONTACTS_CONVERTER
|
119
|
+
|
120
|
+
members :fqdn, :fqdn_unicode, :tld, :can_tld_lock, :tags, :owner, :domain_owner
|
121
|
+
member :sharing_uuid, gandi_key: 'sharing_id'
|
122
|
+
member :name_servers, gandi_key: 'nameservers'
|
123
|
+
member :auth_info, gandi_key: 'authinfo'
|
124
|
+
member :organisation_owner, gandi_key: 'orga_owner'
|
125
|
+
member :uuid, gandi_key: 'id'
|
126
|
+
|
127
|
+
member(
|
128
|
+
:dates,
|
129
|
+
converter: GandiV5::Domain::Dates
|
130
|
+
)
|
131
|
+
member(
|
132
|
+
:sharing_space,
|
133
|
+
gandi_key: 'sharing_space',
|
134
|
+
converter: GandiV5::Domain::SharingSpace
|
135
|
+
)
|
136
|
+
|
137
|
+
member(
|
138
|
+
:auto_renew,
|
139
|
+
gandi_key: 'autorenew',
|
140
|
+
converter: GandiV5::Data::Converter.new(from_gandi: lambda { |hash|
|
141
|
+
break nil if hash.nil?
|
142
|
+
break nil if hash.eql?(true)
|
143
|
+
break GandiV5::Domain::AutoRenew.from_gandi('enabled' => false) if hash.eql?(false)
|
144
|
+
|
145
|
+
GandiV5::Domain::AutoRenew.from_gandi hash
|
146
|
+
})
|
147
|
+
)
|
148
|
+
|
149
|
+
member(
|
150
|
+
:contacts,
|
151
|
+
converter: GandiV5::Data::Converter.new(from_gandi: CONTACTS_CONVERTER)
|
152
|
+
)
|
153
|
+
|
154
|
+
member(
|
155
|
+
:name_server,
|
156
|
+
gandi_key: 'nameserver',
|
157
|
+
converter: GandiV5::Data::Converter.new(from_gandi: ->(hash) { hash&.[]('current')&.to_sym })
|
158
|
+
)
|
159
|
+
member :services, converter: GandiV5::Data::Converter::Symbol, array: true
|
160
|
+
member :status, converter: GandiV5::Data::Converter::Symbol, array: true
|
161
|
+
member :trustee_roles, converter: GandiV5::Data::Converter::Symbol, array: true
|
162
|
+
|
163
|
+
alias domain_uuid uuid
|
164
|
+
|
165
|
+
# rubocop:disable Style/AsciiComments
|
166
|
+
# Returns the string representation of the domain.
|
167
|
+
# @return [String] e.g. "example.com", "😀.com (xn--e28h.uk.com)"
|
168
|
+
# rubocop:enable Style/AsciiComments
|
169
|
+
def to_s
|
170
|
+
string = fqdn_unicode
|
171
|
+
string += " (#{fqdn})" unless fqdn == fqdn_unicode
|
172
|
+
string
|
173
|
+
end
|
174
|
+
|
175
|
+
# Contacts for the domain.
|
176
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-contacts
|
177
|
+
# @return [Hash{:owner, :admin, :bill, :tech => GandiV5::Domain::Contact}]
|
178
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
179
|
+
def contacts
|
180
|
+
@contacts ||= fetch_contacts
|
181
|
+
end
|
182
|
+
|
183
|
+
# Requery Gandi for the domain's contacts.
|
184
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-contacts
|
185
|
+
# @return [Hash{:owner, :admin, :bill, :tech => GandiV5::Domain::Contact}]
|
186
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
187
|
+
def fetch_contacts
|
188
|
+
data = GandiV5.get url('contacts')
|
189
|
+
self.contacts = data.transform_keys(&:to_sym)
|
190
|
+
CONTACTS_CONVERTER.call contacts
|
191
|
+
end
|
192
|
+
|
193
|
+
# Update some of the domain's contacts.
|
194
|
+
# @see https://api.gandi.net/docs/domains#patch-v5-domain-domains-domain-contacts
|
195
|
+
# @param admin [GandiV5::Domain::Contact, #to_gandi, #to_h]
|
196
|
+
# details for the new administrative contact.
|
197
|
+
# @param bill [GandiV5::Domain::Contact, #to_gandi, #to_h]
|
198
|
+
# details for the new billing contact.
|
199
|
+
# @param tech [GandiV5::Domain::Contact, #to_gandi, #to_h]
|
200
|
+
# details for the new technical contact.
|
201
|
+
# @return [Hash{:owner, :admin, :bill, :tech => GandiV5::Domain::Contact}]
|
202
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
203
|
+
def update_contacts(admin: nil, bill: nil, tech: nil)
|
204
|
+
body = {
|
205
|
+
admin: admin.respond_to?(:to_gandi) ? admin.to_gandi : admin,
|
206
|
+
bill: bill.respond_to?(:to_gandi) ? bill.to_gandi : bill,
|
207
|
+
tech: tech.respond_to?(:to_gandi) ? tech.to_gandi : tech
|
208
|
+
}.reject { |_k, v| v.nil? }.to_json
|
209
|
+
|
210
|
+
GandiV5.patch url('contacts'), body
|
211
|
+
fetch_contacts
|
212
|
+
end
|
213
|
+
|
214
|
+
# Renewal information for the domain.
|
215
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-renew
|
216
|
+
# @return [GandiV5::Domain::RenewalInformation]
|
217
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
218
|
+
def renewal_information
|
219
|
+
@renewal_information ||= fetch_renewal_information
|
220
|
+
end
|
221
|
+
|
222
|
+
# Requery Gandi for the domain's renewal information.
|
223
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-renew
|
224
|
+
# @return [GandiV5::Domain::RenewalInformation]
|
225
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
226
|
+
def fetch_renewal_information
|
227
|
+
data = GandiV5.get url('renew')
|
228
|
+
data = data['renew'].merge('contracts' => data['contracts'])
|
229
|
+
@renewal_information = GandiV5::Domain::RenewalInformation.from_gandi data
|
230
|
+
end
|
231
|
+
|
232
|
+
# Renew domain.
|
233
|
+
# Warning! This is not a free operation. Please ensure your prepaid account has enough credit.
|
234
|
+
# @see https://api.gandi.net/docs/domains#post-v5-domain-domains-domain-renew
|
235
|
+
# @param duration [Integer, #to_s] how long to renew for (in years).
|
236
|
+
# @return [String] confirmation message from Gandi.
|
237
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
238
|
+
def renew_for(duration = 1)
|
239
|
+
body = { duration: duration }.to_json
|
240
|
+
data = GandiV5.post url('renew'), body
|
241
|
+
data['message']
|
242
|
+
end
|
243
|
+
|
244
|
+
# TODO: Test when I have a restorable domain
|
245
|
+
# Restoration information for the domain.
|
246
|
+
# @see https://docs.gandi.net/en/domain_names/renew/restore.html
|
247
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-restore
|
248
|
+
# @return [GandiV5::Domain::RestoreInformation]
|
249
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
250
|
+
def restore_information
|
251
|
+
@restore_information ||= fetch_restore_information
|
252
|
+
end
|
253
|
+
|
254
|
+
# TODO: Test when I have a restorable domain
|
255
|
+
# Requery Gandi for the domain's restore information.
|
256
|
+
# @see https://docs.gandi.net/en/domain_names/renew/restore.html
|
257
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-restore
|
258
|
+
# @return [GandiV5::Domain::RestoreInformation]
|
259
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
260
|
+
def fetch_restore_information
|
261
|
+
data = GandiV5.get url('restore')
|
262
|
+
@restore_information = GandiV5::Domain::RestoreInformation.from_gandi data
|
263
|
+
rescue RestClient::NotFound
|
264
|
+
@restore_information = GandiV5::Domain::RestoreInformation.from_gandi restorable: false
|
265
|
+
end
|
266
|
+
|
267
|
+
# Restore an expired domain.
|
268
|
+
# Warning! This is not a free operation. Please ensure your prepaid account has enough credit.
|
269
|
+
# @see https://docs.gandi.net/en/domain_names/renew/restore.html
|
270
|
+
# @see https://api.gandi.net/docs/domains#post-v5-domain-domains-domain-restore
|
271
|
+
# @return [String] The confirmation message from Gandi.
|
272
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
273
|
+
def restore
|
274
|
+
data = GandiV5.post url('restore'), '{}'
|
275
|
+
data['message']
|
276
|
+
end
|
277
|
+
|
278
|
+
# Requery Gandi fo this domain's information.
|
279
|
+
# @return [GandiV5::Domain]
|
280
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
281
|
+
def refresh
|
282
|
+
data = GandiV5.get url
|
283
|
+
from_gandi data
|
284
|
+
auto_renew.domain = self
|
285
|
+
end
|
286
|
+
|
287
|
+
# Create (register) a new domain.
|
288
|
+
# Warning! This is not a free operation. Please ensure your prepaid account has enough credit.
|
289
|
+
# @see https://api.gandi.net/docs/domains#post-v5-domain-domains
|
290
|
+
# @param fqdn [String, #to_s] the fully qualified domain name to create.
|
291
|
+
# @param owner [GandiV5::Domain::Contact, #to_gandi, #to_h] (required)
|
292
|
+
# the owner of the new domain.
|
293
|
+
# @param admin [GandiV5::Domain::Contact, #to_gandi, #to_h] (optional, defaults to owner)
|
294
|
+
# the administrative contact for the new domain.
|
295
|
+
# @param bill [GandiV5::Domain::Contact, #to_gandi, #to_h] (optional, defaults to owner)
|
296
|
+
# the billing contact for the new domain.
|
297
|
+
# @param tech [GandiV5::Domain::Contact, #to_gandi, #to_h] (optional, defaults to owner)
|
298
|
+
# the technical contact for the new domain.
|
299
|
+
# @param claims [String] (optional) unknown - not documented at Gandi.
|
300
|
+
# @param currency ["EUR", "USD", "GBP", "TWD", "CNY"] (optional)
|
301
|
+
# the currency you wish to be charged in.
|
302
|
+
# @param duration [Integer] (optional, default 1, minimum 1 maximum 10)
|
303
|
+
# how many years to register for.
|
304
|
+
# @param enforce_premium [Boolean] (optional)
|
305
|
+
# must be set to true if the domain is a premium domain.
|
306
|
+
# @param extra_parameters [Hash, #to_gandi, #to_json] (optional)
|
307
|
+
# unknown - not documented at Gandi.
|
308
|
+
# @param lang [String] (optional)
|
309
|
+
# ISO-639-2 language code of the domain, required for some IDN domains.
|
310
|
+
# @param nameserver_ips [Hash<String => Array<String>>, #to_gandi, #to_json] (optional)
|
311
|
+
# For glue records only - dictionnary associating a nameserver to a list of IP addresses.
|
312
|
+
# @param nameservers [Array<String>, #to_gandi, #to_json] (optional)
|
313
|
+
# List of nameservers. Gandi's LiveDNS nameservers are used if omitted..
|
314
|
+
# @param price [Numeric, #to_gandi, #to_json] (optional) unknown - not documented at Gandi.
|
315
|
+
# @param reselle_id [String, #to_gandi, #to_json] (optional) unknown - not documented at Gandi.
|
316
|
+
# @param smd [String, #to_gandi, #to_json] (optional)
|
317
|
+
# Contents of a Signed Mark Data file (used for newgtld sunrises, tld_period must be sunrise).
|
318
|
+
# @param tld_period ["sunrise", "landrush", "eap1", "eap2", "eap3", "eap4", "eap5", "eap6",
|
319
|
+
# "eap7", "eap8", "eap9", "golive", #to_gandi, #to_json] (optional)
|
320
|
+
# @see https://docs.gandi.net/en/domain_names/register/new_gtld.html
|
321
|
+
# @param dry_run [Boolean] whether the details should be checked
|
322
|
+
# instead of actually creating the domain.
|
323
|
+
# @return [Hash] if actually creating, you get what Gandi returns.
|
324
|
+
# @return [Hash] if doing a dry run, you get what Gandi returns.
|
325
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
326
|
+
# TODO: Return created domain unless dry_run
|
327
|
+
def self.create(fqdn, dry_run: false, **params)
|
328
|
+
fail ArgumentError, 'missing keyword: owner' unless params.key?(:owner)
|
329
|
+
|
330
|
+
body = params.merge(fqdn: fqdn)
|
331
|
+
.transform_values { |val| val.respond_to?(:to_gandi) ? val.to_gandi : val }
|
332
|
+
.to_json
|
333
|
+
GandiV5.post url, body, 'Dry-Run': dry_run ? 1 : 0
|
334
|
+
end
|
335
|
+
|
336
|
+
# Get information on a domain.
|
337
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain
|
338
|
+
# @param fqdn [String, #to_s] the fully qualified domain name to fetch.
|
339
|
+
# @return [GandiV5::Domain]
|
340
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
341
|
+
def self.fetch(fqdn)
|
342
|
+
data = GandiV5.get url(fqdn)
|
343
|
+
domain = from_gandi data
|
344
|
+
domain.auto_renew.domain = fqdn
|
345
|
+
domain
|
346
|
+
end
|
347
|
+
|
348
|
+
# List domains.
|
349
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-domains
|
350
|
+
# @param page [#each<Integer, #to_s>] the page(s) of results to retrieve.
|
351
|
+
# If page is not provided keep querying until an empty list is returned.
|
352
|
+
# If page responds to .each then iterate until an empty list is returned.
|
353
|
+
# @param per_page [Integer, #to_s] (optional default 100) how many results ot get per page.
|
354
|
+
# @param fqdn [String, #to_s] (optional)
|
355
|
+
# filters the list by domain name, with optional patterns.
|
356
|
+
# e.g. "example.net", "example.*", "*ample.com"
|
357
|
+
# @param sort_by [String, #to_s] (optional default "fqdn") how to sort the list.
|
358
|
+
# @param tld [String, #to_s] (optional) used to filter by just the top level domain.
|
359
|
+
# @return [Array<GandiV5::Domain>]
|
360
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
361
|
+
def self.list(page: (1..), per_page: 100, **params)
|
362
|
+
page = [page.to_i] unless page.respond_to?(:each)
|
363
|
+
|
364
|
+
domains = []
|
365
|
+
page.each do |page_number|
|
366
|
+
data = GandiV5.get url, params: params.merge(page: page_number, per_page: per_page)
|
367
|
+
break if data.empty?
|
368
|
+
|
369
|
+
domains += data.map { |domain| from_gandi domain }
|
370
|
+
break if data.count < per_page
|
371
|
+
end
|
372
|
+
domains
|
373
|
+
end
|
374
|
+
|
375
|
+
# Check domain availability and pricing.
|
376
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-check
|
377
|
+
# @param fqdn [String, #to_s] the fully qualified domain name to check.
|
378
|
+
# @param country [String, #to_s] (optional) ISO country code for which taxes are to be applied.
|
379
|
+
# @param currency [String, #to_s] (optional) request price for a specific ISO currency code.
|
380
|
+
# @param duration_unit [String, #to_s] (optional) define the unit for max_duration.
|
381
|
+
# @param extension [String, #to_s] (optional) query a specific extension for product options.
|
382
|
+
# @param grid [String, #to_s] (optional) request price for a specific rate.
|
383
|
+
# @param lang [String, #to_s] (optional) language code.
|
384
|
+
# @param max_duration [Integer, #to_s] (optional)
|
385
|
+
# set a limit on the duration range for returned prices.
|
386
|
+
# @param period [String, #to_s] (optional) specific registration period to query.
|
387
|
+
# @param _ [Array<:create, :renew, :transfer etc.>] (optional default [:create])
|
388
|
+
# list of at least 1 process for which pricing is to be made.
|
389
|
+
# @param sharing_id [String, #to_s] (optional) organization for which the pricing is to be made.
|
390
|
+
# @return [Hash]
|
391
|
+
# TODO: Return an Availabillity object ???
|
392
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
393
|
+
def self.availability(fqdn, **options)
|
394
|
+
GandiV5.get "#{BASE}domain/check", params: { name: fqdn }.merge(options)
|
395
|
+
end
|
396
|
+
|
397
|
+
# List of available TLDs.
|
398
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-tlds
|
399
|
+
# @return Array<String>
|
400
|
+
# TODO: Maybe return an array of TLD objects ???
|
401
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
402
|
+
def self.tlds
|
403
|
+
GandiV5.get("#{BASE}domain/tlds")
|
404
|
+
.map { |hash| hash['name'] }
|
405
|
+
end
|
406
|
+
|
407
|
+
# Get TLD information.
|
408
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-tlds-name
|
409
|
+
# @param name [String, #to_s] the top level domain to get information for.
|
410
|
+
# @return [Hash]
|
411
|
+
# TODO: Return a TLD object ???
|
412
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
413
|
+
def self.tld(name)
|
414
|
+
GandiV5.get("#{BASE}domain/tlds/#{CGI.escape name}").transform_keys(&:to_sym)
|
415
|
+
end
|
416
|
+
|
417
|
+
private
|
418
|
+
|
419
|
+
def url(extra = nil)
|
420
|
+
"#{BASE}domain/domains/" +
|
421
|
+
CGI.escape(fqdn) +
|
422
|
+
(extra ? "/#{extra}" : '')
|
423
|
+
end
|
424
|
+
|
425
|
+
def self.url(fqdn = nil)
|
426
|
+
"#{BASE}domain/domains" +
|
427
|
+
(fqdn ? "/#{CGI.escape fqdn}" : '')
|
428
|
+
end
|
429
|
+
private_class_method :url
|
430
|
+
end
|
431
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# TODO: Allow enable/disable from here too ???
|
4
|
+
|
5
|
+
class GandiV5
|
6
|
+
class Email
|
7
|
+
class Mailbox
|
8
|
+
# Status of a mailbox's auto responder.
|
9
|
+
# @see https://api.gandi.net/docs/email#get-v5-email-mailboxes-domain-mailbox_id
|
10
|
+
# @!attribute [r] enabled
|
11
|
+
# @return [Boolean]
|
12
|
+
# @!attribute [r] starts_at
|
13
|
+
# @return [nil, Time]
|
14
|
+
# @!attribute [r] ends_at
|
15
|
+
# @return [nil, Time]
|
16
|
+
# @!attribute [r] message
|
17
|
+
# @return [nil, String]
|
18
|
+
class Responder
|
19
|
+
include GandiV5::Data
|
20
|
+
|
21
|
+
members :enabled, :message
|
22
|
+
member :starts_at, converter: GandiV5::Data::Converter::Time
|
23
|
+
member :ends_at, converter: GandiV5::Data::Converter::Time
|
24
|
+
|
25
|
+
# Check if this responder is currently active.
|
26
|
+
# @return [Boolean] whether the responder is enabled,
|
27
|
+
# started in the past and ends in the future.
|
28
|
+
def active?
|
29
|
+
enabled &&
|
30
|
+
(starts_at.nil? || starts_at < Time.now) &&
|
31
|
+
(ends_at.nil? || ends_at > Time.now)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|