gandi_v5 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.
- 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
|