gandi_v5 0.1.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +14 -4
- data/.travis.yml +16 -1
- data/CHANGELOG.md +80 -2
- data/FUNDING.yml +10 -0
- data/Guardfile +5 -6
- data/LICENSE.md +2 -6
- data/README.md +17 -23
- data/gandi_v5.gemspec +4 -3
- data/lib/gandi_v5.rb +54 -15
- data/lib/gandi_v5/billing.rb +2 -4
- data/lib/gandi_v5/billing/info.rb +0 -2
- data/lib/gandi_v5/data.rb +1 -2
- data/lib/gandi_v5/data/converter.rb +0 -4
- data/lib/gandi_v5/data/converter/integer.rb +26 -0
- data/lib/gandi_v5/domain.rb +201 -101
- data/lib/gandi_v5/domain/auto_renew.rb +4 -4
- data/lib/gandi_v5/domain/availability.rb +46 -0
- data/lib/gandi_v5/domain/availability/product.rb +49 -0
- data/lib/gandi_v5/domain/availability/product/period.rb +24 -0
- data/lib/gandi_v5/domain/availability/product/price.rb +36 -0
- data/lib/gandi_v5/domain/availability/tax.rb +20 -0
- data/lib/gandi_v5/domain/live_dns.rb +42 -0
- data/lib/gandi_v5/domain/renewal_information.rb +0 -3
- data/lib/gandi_v5/domain/sharing_space.rb +10 -2
- data/lib/gandi_v5/domain/tld.rb +57 -0
- data/lib/gandi_v5/email.rb +0 -4
- data/lib/gandi_v5/email/forward.rb +108 -0
- data/lib/gandi_v5/email/mailbox.rb +85 -24
- data/lib/gandi_v5/email/mailbox/responder.rb +43 -2
- data/lib/gandi_v5/email/offer.rb +2 -2
- data/lib/gandi_v5/email/slot.rb +52 -18
- data/lib/gandi_v5/error.rb +0 -2
- data/lib/gandi_v5/error/gandi_error.rb +2 -2
- data/lib/gandi_v5/live_dns.rb +20 -4
- data/lib/gandi_v5/live_dns/domain.rb +21 -150
- data/lib/gandi_v5/live_dns/has_zone_records.rb +153 -0
- data/lib/gandi_v5/live_dns/record_set.rb +1 -1
- data/lib/gandi_v5/live_dns/zone.rb +24 -165
- data/lib/gandi_v5/live_dns/zone/snapshot.rb +27 -8
- data/lib/gandi_v5/organization.rb +39 -6
- data/lib/gandi_v5/organization/customer.rb +90 -0
- data/lib/gandi_v5/version.rb +1 -1
- data/spec/.rubocop.yml +9 -2
- data/spec/features/domain_spec.rb +2 -2
- data/spec/features/livedns_zone_spec.rb +12 -13
- data/spec/fixtures/bodies/GandiV5_Billing/{info.yaml → info.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_Domain/{get.yaml → fetch.yml} +8 -0
- data/spec/fixtures/bodies/GandiV5_Domain/{fetch_contacts.yaml → fetch_contacts.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_Domain/fetch_glue_records.yml +7 -0
- data/spec/fixtures/bodies/GandiV5_Domain/fetch_livedns.yml +6 -0
- data/spec/fixtures/bodies/GandiV5_Domain/fetch_name_servers.yml +2 -0
- data/spec/fixtures/bodies/GandiV5_Domain/{renewal_info.yaml → fetch_renewal_info.yml} +0 -3
- data/spec/fixtures/bodies/GandiV5_Domain/{restore_info.yaml → fetch_restore_info.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_Domain/{list.yaml → list.yml} +1 -0
- data/spec/fixtures/bodies/{GandiV5_Domain/availability.yaml → GandiV5_Domain_Availability/fetch.yml} +0 -0
- data/spec/fixtures/bodies/{GandiV5_Domain/tld.yaml → GandiV5_Domain_TLD/fetch.yml} +0 -0
- data/spec/fixtures/bodies/{GandiV5_Domain/tlds.yaml → GandiV5_Domain_TLD/list.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_Email_Forward/list.yml +6 -0
- data/spec/fixtures/bodies/GandiV5_Email_Mailbox/{get.yaml → fetch.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_Email_Mailbox/{list.yaml → list.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_Email_Slot/{get.yaml → fetch.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_Email_Slot/{list.yaml → list.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/{get.yaml → fetch.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/{list.yaml → list.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/{get.yaml → fetch.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/{list.yaml → list.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/{get.yaml → fetch.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/list.yml +3 -0
- data/spec/fixtures/bodies/GandiV5_Organization/{get.yaml → fetch.yml} +0 -0
- data/spec/fixtures/bodies/GandiV5_Organization/list.yml +7 -0
- data/spec/fixtures/bodies/GandiV5_Organization_Customer/list.yml +8 -0
- data/spec/fixtures/vcr/Domain_features/List_domains.yml +2 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/units/gandi_v5/billing_spec.rb +4 -4
- data/spec/units/gandi_v5/data/converter/integer_spec.rb +16 -0
- data/spec/units/gandi_v5/domain/auto_renew_spec.rb +5 -5
- data/spec/units/gandi_v5/domain/availability/product/period_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/availability/product/price_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/availability/product_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/availability/tax_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/availability_spec.rb +43 -0
- data/spec/units/gandi_v5/domain/live_dns_spec.rb +45 -0
- data/spec/units/gandi_v5/domain/tld_spec.rb +29 -0
- data/spec/units/gandi_v5/domain_spec.rb +359 -91
- data/spec/units/gandi_v5/email/forward_spec.rb +121 -0
- data/spec/units/gandi_v5/email/mailbox/responder_spec.rb +52 -0
- data/spec/units/gandi_v5/email/mailbox_spec.rb +174 -33
- data/spec/units/gandi_v5/email/offer_spec.rb +1 -1
- data/spec/units/gandi_v5/email/slot_spec.rb +113 -17
- data/spec/units/gandi_v5/live_dns/domain_spec.rb +73 -43
- data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +32 -3
- data/spec/units/gandi_v5/live_dns/zone_spec.rb +70 -52
- data/spec/units/gandi_v5/live_dns_spec.rb +24 -0
- data/spec/units/gandi_v5/organization/customer_spec.rb +81 -0
- data/spec/units/gandi_v5/organization_spec.rb +52 -1
- data/spec/units/gandi_v5_spec.rb +56 -19
- metadata +71 -29
- data/TODO.md +0 -29
@@ -21,10 +21,10 @@ class GandiV5
|
|
21
21
|
|
22
22
|
# Disable auto renewal for the associated domain.
|
23
23
|
# @return [String] The confirmation message from Gandi.
|
24
|
-
# @raise [GandiV5::Error::GandiError
|
24
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
25
25
|
def disable
|
26
26
|
body = { enabled: false }.to_json
|
27
|
-
data = GandiV5.patch url, body
|
27
|
+
_response, data = GandiV5.patch url, body
|
28
28
|
self.enabled = false
|
29
29
|
data['message']
|
30
30
|
end
|
@@ -35,7 +35,7 @@ class GandiV5
|
|
35
35
|
# @return [String] The confirmation message from Gandi.
|
36
36
|
# @raise [ArgumentError] if duration is invalid (not 1 to 9 (inclusive)).
|
37
37
|
# @raise [ArgumentError] if org_id is not passed and not set for this domain.
|
38
|
-
# @raise [GandiV5::Error::GandiError
|
38
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
39
39
|
def enable(duration: self.duration || 1, org_id: self.org_id)
|
40
40
|
fail ArgumentError, 'duration can not be less than 1' if duration < 1
|
41
41
|
fail ArgumentError, 'duration can not be more than 9' if duration > 9
|
@@ -47,7 +47,7 @@ class GandiV5
|
|
47
47
|
org_id: org_id
|
48
48
|
}.to_json
|
49
49
|
|
50
|
-
data = GandiV5.patch url, body
|
50
|
+
_response, data = GandiV5.patch url, body
|
51
51
|
self.enabled = true
|
52
52
|
self.duration = duration
|
53
53
|
self.org_id = org_id
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class Domain
|
5
|
+
# Information about the availabillity of processes on a domain.
|
6
|
+
# @!attribute [r] currency
|
7
|
+
# @return [String]
|
8
|
+
# @!attribute [r] grid
|
9
|
+
# @return [String]
|
10
|
+
# @!attribute [r] products
|
11
|
+
# @return [Arrav<GandiV5::Domain::Availability::Product>]
|
12
|
+
# @!attribute [r] taxes
|
13
|
+
# @return [Array<GandiV5::Domain::Availability::Tax>]
|
14
|
+
class Availability
|
15
|
+
include GandiV5::Data
|
16
|
+
|
17
|
+
members :currency, :grid
|
18
|
+
member :products, converter: GandiV5::Domain::Availability::Product, array: true
|
19
|
+
member :taxes, converter: GandiV5::Domain::Availability::Tax, array: true
|
20
|
+
|
21
|
+
# Check domain availability and pricing.
|
22
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-check
|
23
|
+
# @param fqdn [String, #to_s] the fully qualified domain name to check.
|
24
|
+
# @param country [String, #to_s] (optional)
|
25
|
+
# ISO country code for which taxes are to be applied.
|
26
|
+
# @param currency [String, #to_s] (optional) request price for a specific ISO currency code.
|
27
|
+
# @param duration_unit [String, #to_s] (optional) define the unit for max_duration.
|
28
|
+
# @param extension [String, #to_s] (optional) query a specific extension for product options.
|
29
|
+
# @param grid [String, #to_s] (optional) request price for a specific rate.
|
30
|
+
# @param lang [String, #to_s] (optional) language code.
|
31
|
+
# @param max_duration [Integer, #to_s] (optional)
|
32
|
+
# set a limit on the duration range for returned prices.
|
33
|
+
# @param period [String, #to_s] (optional) specific registration period to query.
|
34
|
+
# @param processes [Array<:create, :renew, :transfer etc.>] (optional default [:create])
|
35
|
+
# list of at least 1 process for which pricing is to be made.
|
36
|
+
# @param sharing_id [String, #to_s] (optional)
|
37
|
+
# organization for which the pricing is to be made.
|
38
|
+
# @return [GandiV5::Domain::Availability]
|
39
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
40
|
+
def self.fetch(fqdn, **options)
|
41
|
+
_response, data = GandiV5.get("#{BASE}domain/check", params: { name: fqdn }.merge(options))
|
42
|
+
GandiV5::Domain::Availability.from_gandi data
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class Domain
|
5
|
+
class Availability
|
6
|
+
# Information about an available product.
|
7
|
+
# @!attribute [r] name
|
8
|
+
# @return [String]
|
9
|
+
# @!attribute [r] prices
|
10
|
+
# @return [Array<GandiV5::Domain::Availability::Product::Price>]
|
11
|
+
# @!attribute [r] periods
|
12
|
+
# @return [Array<GandiV5::Domain::Availability::Product::Period>]
|
13
|
+
# @!attribute [r] taxes
|
14
|
+
# @return [Array<GandiV5::Domain::Availability::Tax>]
|
15
|
+
# @!attribute [r] process
|
16
|
+
# @return [Symbol]
|
17
|
+
# @!attribute [r] status
|
18
|
+
# @return [Symbol]
|
19
|
+
class Product
|
20
|
+
include GandiV5::Data
|
21
|
+
|
22
|
+
STATUSES = {
|
23
|
+
available: 'Domain name is available',
|
24
|
+
available_reserved: 'Domain name reserved under special conditions',
|
25
|
+
available_preorder: 'Domain name can be pre-ordered',
|
26
|
+
unavailable: 'Domain name is not available',
|
27
|
+
unavailable_premium: 'Domain name is not available',
|
28
|
+
unavailable_restricted: 'Domain name is not available (forbidden)',
|
29
|
+
error_invalid: 'Provided value is not a valid domain name',
|
30
|
+
error_refused: 'Service is temporarily down',
|
31
|
+
error_timeout: 'Service timed out, try the method again later',
|
32
|
+
error_unknown: 'Internal server error',
|
33
|
+
reserved_corporate: 'The TLD for the given domain name is reserved for ' \
|
34
|
+
'Gandi Corporate Services customers',
|
35
|
+
pending: 'Result is not yet ready, try the method again later',
|
36
|
+
error_eoi: 'The TLD for the given domain name is in an ' \
|
37
|
+
'Expression of Interest (EOI) period'
|
38
|
+
}.freeze
|
39
|
+
|
40
|
+
members :name
|
41
|
+
member :prices, converter: GandiV5::Domain::Availability::Product::Price, array: true
|
42
|
+
member :periods, converter: GandiV5::Domain::Availability::Product::Period, array: true
|
43
|
+
member :process, converter: GandiV5::Data::Converter::Symbol
|
44
|
+
member :status, converter: GandiV5::Data::Converter::Symbol
|
45
|
+
member :taxes, converter: GandiV5::Domain::Availability::Tax, array: true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class Domain
|
5
|
+
class Availability
|
6
|
+
class Product
|
7
|
+
# Information about an available product.
|
8
|
+
# @!attribute [r] name
|
9
|
+
# @return [String]
|
10
|
+
# @!attribute [r]
|
11
|
+
# @return [Time] starts_at
|
12
|
+
# @!attribute [r]
|
13
|
+
# @return [Time, nil] ends_at
|
14
|
+
class Period
|
15
|
+
include GandiV5::Data
|
16
|
+
|
17
|
+
members :name
|
18
|
+
member :starts_at, converter: GandiV5::Data::Converter::Time
|
19
|
+
member :ends_at, converter: GandiV5::Data::Converter::Time
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class Domain
|
5
|
+
class Availability
|
6
|
+
class Product
|
7
|
+
# Information about an available product.
|
8
|
+
# @!attribute [r] duration_unit
|
9
|
+
# @return [String] time unit for the duration (e.g. y)
|
10
|
+
# @!attribute [r] max_duration
|
11
|
+
# @return [Integer] maximum duration for which this price unit applies
|
12
|
+
# @!attribute [r] min_duration
|
13
|
+
# @return [Integer] minimum duration for which this price unit applies.
|
14
|
+
# @!attribute [r] price_after_taxes
|
15
|
+
# @return [Numeric] pricing after tax is applied
|
16
|
+
# @!attribute [r] price_before_taxes
|
17
|
+
# @return [Numeric] pricing before tax is applied
|
18
|
+
# @!attribute [r] discount
|
19
|
+
# @return [Boolean, nil] whether a discount is active on this price unit
|
20
|
+
# @!attribute [r] normal_price_after_taxes
|
21
|
+
# @return [Numeric, nil] pricing after tax is applied, when no discount applies
|
22
|
+
# @!attribute [r] normal_price_before_taxes
|
23
|
+
# @return [Numeric, nil] pricing before tax is applied, when no discount applies
|
24
|
+
# @!attribute [r] type
|
25
|
+
# @return [String, nil]
|
26
|
+
class Price
|
27
|
+
include GandiV5::Data
|
28
|
+
|
29
|
+
members :duration_unit, :max_duration, :min_duration,
|
30
|
+
:price_after_taxes, :price_before_taxes,
|
31
|
+
:discount, :normal_price_after_taxes, :normal_price_after_taxes, :type
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class Domain
|
5
|
+
class Availability
|
6
|
+
# Information about tax due on a process/product.
|
7
|
+
# @!attribute [r] name
|
8
|
+
# @return [String] name of the tax (e.g. VAT)
|
9
|
+
# @!attribute [r] rate
|
10
|
+
# @return [Numeric] percentage rate of the tax (e.g. 20)
|
11
|
+
# @!attribute [r] type
|
12
|
+
# @return [String] type of the tax (e.g. service)
|
13
|
+
class Tax
|
14
|
+
include GandiV5::Data
|
15
|
+
|
16
|
+
members :name, :rate, :type
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class Domain
|
5
|
+
# LiveDNS information for a domain.
|
6
|
+
# @!attribute [r] current
|
7
|
+
# @return [:classic, :livedns, :other]
|
8
|
+
# type of nameservers currently set. classic corresponds to Gandi's classic nameservers,
|
9
|
+
# livedns is for the new, default, Gandi nameservers and other is for custom nameservers.
|
10
|
+
# @!attribute [r] name_servers
|
11
|
+
# @return [Array<String>] list of current nameservers.
|
12
|
+
# @!attribute [r] dnssec_available
|
13
|
+
# @return [nil, Boolean] whether DNSSEC may be applied to the domain.
|
14
|
+
# @!attribute [r] livednssec_available
|
15
|
+
# @return [nil, Boolean] whether DNSSEC with liveDNS may be applied to this domain.
|
16
|
+
class LiveDNS
|
17
|
+
include GandiV5::Data
|
18
|
+
|
19
|
+
members :dnssec_available, :livednssec_available
|
20
|
+
member :name_servers, gandi_key: 'nameservers'
|
21
|
+
member :current, converter: GandiV5::Data::Converter::Symbol
|
22
|
+
|
23
|
+
# Check if classic DNS is being used.
|
24
|
+
# @return [Boolean]
|
25
|
+
def classic?
|
26
|
+
current == :classic
|
27
|
+
end
|
28
|
+
|
29
|
+
# Check if custom DNS is being used.
|
30
|
+
# @return [Boolean]
|
31
|
+
def custom?
|
32
|
+
current == :custom
|
33
|
+
end
|
34
|
+
|
35
|
+
# Check if LiveDNS is being used.
|
36
|
+
# @return [Boolean]
|
37
|
+
def livedns?
|
38
|
+
current == :livedns
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -17,8 +17,6 @@ class GandiV5
|
|
17
17
|
# @return [Integer]
|
18
18
|
# @!attribute [r] minimum
|
19
19
|
# @return [Integer]
|
20
|
-
# @!attribute [r] contracts
|
21
|
-
# @return [Array<GandiV5::Domain::Contract>]
|
22
20
|
class RenewalInformation
|
23
21
|
include GandiV5::Data
|
24
22
|
|
@@ -26,7 +24,6 @@ class GandiV5
|
|
26
24
|
|
27
25
|
member :begins_at, converter: GandiV5::Data::Converter::Time
|
28
26
|
member :ends_at, converter: GandiV5::Data::Converter::Time
|
29
|
-
member :contracts, converter: GandiV5::Domain::Contract, array: true
|
30
27
|
|
31
28
|
# Check if the domain is currently renewable.
|
32
29
|
# @return [Boolean]
|
@@ -7,14 +7,22 @@ class GandiV5
|
|
7
7
|
# @return [String]
|
8
8
|
# @!attribute [r] name
|
9
9
|
# @return [String]
|
10
|
+
# @!attribute [r] type
|
11
|
+
# @return [String]
|
10
12
|
# @!attribute [r] reseller
|
11
13
|
# @return [nil, Boolean]
|
14
|
+
# @!attribute [r] reseller_details
|
15
|
+
# @return [nil, GandiV5::Domain::SharingSpace]
|
12
16
|
class SharingSpace
|
13
17
|
include GandiV5::Data
|
14
18
|
|
15
|
-
members :name, :reseller
|
19
|
+
members :name, :type, :reseller
|
16
20
|
member :uuid, gandi_key: 'id'
|
17
|
-
|
21
|
+
member(
|
22
|
+
:reseller_details,
|
23
|
+
gandi_key: 'sharing_space',
|
24
|
+
converter: GandiV5::Domain::SharingSpace
|
25
|
+
)
|
18
26
|
alias sharing_space_uuid uuid
|
19
27
|
end
|
20
28
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class Domain
|
5
|
+
# Information about a specific TLD (Top Level Domain).
|
6
|
+
# @!attribute [r] name
|
7
|
+
# @return [String]
|
8
|
+
# @!attribute [r] full_tld
|
9
|
+
# @return [String]
|
10
|
+
# @!attribute [r] authinfo_for_transfer
|
11
|
+
# @return [Boolean] whether authinfo is required for a transfer.
|
12
|
+
# @!attribute [r] category
|
13
|
+
# @return [String]
|
14
|
+
# @!attribute [r] change_owner
|
15
|
+
# @return [Boolean] whther changing owner is pemritted.
|
16
|
+
# @!attribute [r] corporate
|
17
|
+
# @return [Boolean] whether this is a corporate TLD.
|
18
|
+
# @!attribute [r] ext_trade
|
19
|
+
# @return [Boolean]
|
20
|
+
# @!attribute [r] lock
|
21
|
+
# @return [Boolean]
|
22
|
+
class TLD
|
23
|
+
include GandiV5::Data
|
24
|
+
|
25
|
+
members :name, :full_tld, :authinfo_for_transfer, :change_owner, :corporate, :ext_trade, :lock
|
26
|
+
member :category, converter: GandiV5::Data::Converter::Symbol
|
27
|
+
|
28
|
+
# List of available TLDs.
|
29
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-tlds
|
30
|
+
# @return Array<GandiV5::Domain::TLD>
|
31
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
32
|
+
def self.list
|
33
|
+
GandiV5.get(url)
|
34
|
+
.last
|
35
|
+
.map { |tld| GandiV5::Domain::TLD.from_gandi tld }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Get TLD information.
|
39
|
+
# @see https://api.gandi.net/docs/domains#get-v5-domain-tlds-name
|
40
|
+
# @param name [String, #to_s] the top level domain to get information for.
|
41
|
+
# @return [GandiV5::Domain::TLD]
|
42
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
43
|
+
def self.fetch(name)
|
44
|
+
_response, data = GandiV5.get url(name)
|
45
|
+
GandiV5::Domain::TLD.from_gandi data
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def self.url(name = nil)
|
51
|
+
"#{BASE}domain/tlds" +
|
52
|
+
(name ? "/#{CGI.escape name}" : '')
|
53
|
+
end
|
54
|
+
private_class_method :url
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/gandi_v5/email.rb
CHANGED
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class Email
|
5
|
+
# A forwarding address that lives within a domain.
|
6
|
+
# @see https://docs.gandi.net/en/gandimail/forwarding_and_aliases/
|
7
|
+
# @!attribute [r] source
|
8
|
+
# @return [String] the source email address ("alice" rather than "alice@example.com").
|
9
|
+
# @!attribute [r] destinations
|
10
|
+
# @return [Array<String>] list of destination email addresses.
|
11
|
+
# @!attribute [r] fqdn
|
12
|
+
# @return [String] domain name.
|
13
|
+
class Forward
|
14
|
+
include GandiV5::Data
|
15
|
+
|
16
|
+
members :source, :fqdn
|
17
|
+
member :destinations, array: true
|
18
|
+
|
19
|
+
# Delete the forwarding.
|
20
|
+
# @see https://api.gandi.net/docs/email/#delete-v5-email-forwards-domain-source
|
21
|
+
# @return [String] The confirmation message from Gandi.
|
22
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
23
|
+
def delete
|
24
|
+
_response, data = GandiV5.delete url
|
25
|
+
data['message']
|
26
|
+
end
|
27
|
+
|
28
|
+
# Update the forwarding.
|
29
|
+
# @see https://api.gandi.net/docs/email/#put-v5-email-forwards-domain-source
|
30
|
+
# @param destinations [Array<String, #to_s>] new list of destination email addresses.
|
31
|
+
# @return [String] The confirmation message from Gandi.
|
32
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
33
|
+
def update(*destinations)
|
34
|
+
fail ArgumentError, 'destinations can\'t be empty' if destinations.none?
|
35
|
+
|
36
|
+
_response, data = GandiV5.put url, { destinations: destinations }.to_json
|
37
|
+
@destinations = destinations.map(&:to_s)
|
38
|
+
data['message']
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the string representation of the forwarding.
|
42
|
+
# @return [String]
|
43
|
+
def to_s
|
44
|
+
"#{source}@#{fqdn} -> #{destinations.join(', ')}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Create a new forward.
|
48
|
+
# @see https://api.gandi.net/docs/email/#post-v5-email-forwards-domain
|
49
|
+
# @param fqdn [String, #to_s] the fully qualified domain name for the forward.
|
50
|
+
# @param source [String, #to_s]
|
51
|
+
# the source email address ("alice" rather than "alice@example.com").
|
52
|
+
# @param destinations [Array<String, #to_s>] list of destination email addresses.
|
53
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
54
|
+
def self.create(fqdn, source, *destinations)
|
55
|
+
fail ArgumentError, 'destinations can\'t be empty' if destinations.none?
|
56
|
+
|
57
|
+
body = {
|
58
|
+
source: source,
|
59
|
+
destinations: destinations
|
60
|
+
}.to_json
|
61
|
+
_response, _data = GandiV5.post url(fqdn), body
|
62
|
+
|
63
|
+
new fqdn: fqdn, source: source, destinations: destinations
|
64
|
+
end
|
65
|
+
|
66
|
+
# List forwards for a domain.
|
67
|
+
# @see https://api.gandi.net/docs/email/#get-v5-email-forwards-domain
|
68
|
+
# @param fqdn [String, #to_s] the fully qualified domain name for the forwards.
|
69
|
+
# @param page [Integer, #each<Integer>] which page(s) of results to get.
|
70
|
+
# If page is not provided keep querying until an empty list is returned.
|
71
|
+
# If page responds to .each then iterate until an empty list is returned.
|
72
|
+
# @param per_page [Integer, #to_s] (optional default 100) how many results ot get per page.
|
73
|
+
# @param sort_by [#to_s] (optional default "login")
|
74
|
+
# how to sort the results ("login", "-login").
|
75
|
+
# @param source [String] (optional) filter the source (pattern)
|
76
|
+
# e.g. ("alice" "*lice", "alic*").
|
77
|
+
# @return [Array<GandiV5::Email::Forward>]
|
78
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
79
|
+
def self.list(fqdn, page: (1..), **params)
|
80
|
+
page = [page.to_i] unless page.respond_to?(:each)
|
81
|
+
|
82
|
+
params.reject! { |_k, v| v.nil? }
|
83
|
+
|
84
|
+
mailboxes = []
|
85
|
+
page.each do |page_number|
|
86
|
+
_response, data = GandiV5.get url(fqdn), params: params.merge(page: page_number)
|
87
|
+
break if data.empty?
|
88
|
+
|
89
|
+
mailboxes += data.map { |mailbox| from_gandi mailbox.merge(fqdn: fqdn) }
|
90
|
+
break if data.count < params.fetch(:per_page, 100)
|
91
|
+
end
|
92
|
+
mailboxes
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def url
|
98
|
+
"#{BASE}email/forwards/#{CGI.escape fqdn}/#{CGI.escape source}"
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.url(fqdn, source = nil)
|
102
|
+
"#{BASE}email/forwards/#{CGI.escape fqdn}" +
|
103
|
+
(source ? "/#{CGI.escape source}" : '')
|
104
|
+
end
|
105
|
+
private_class_method :url
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|