gandi_v5 0.1.0 → 0.2.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 +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +1 -0
- data/CHANGELOG.md +44 -2
- data/Guardfile +5 -6
- data/README.md +5 -5
- data/doc/GandiV5/Billing/Info/Prepaid.html +817 -0
- data/doc/GandiV5/Billing/Info.html +641 -0
- data/doc/GandiV5/Billing.html +293 -0
- data/doc/GandiV5/Data/ClassMethods.html +223 -0
- data/doc/GandiV5/Data/Converter/ArrayOf.html +413 -0
- data/doc/GandiV5/Data/Converter/Symbol.html +322 -0
- data/doc/GandiV5/Data/Converter/Time.html +330 -0
- data/doc/GandiV5/Data/Converter.html +433 -0
- data/doc/GandiV5/Data.html +785 -0
- data/doc/GandiV5/Domain/AutoRenew.html +1237 -0
- data/doc/GandiV5/Domain/Availability/Product/Period.html +220 -0
- data/doc/GandiV5/Domain/Availability/Product/Price.html +1031 -0
- data/doc/GandiV5/Domain/Availability/Product.html +988 -0
- data/doc/GandiV5/Domain/Availability/Tax.html +440 -0
- data/doc/GandiV5/Domain/Availability.html +1020 -0
- data/doc/GandiV5/Domain/Contact.html +4459 -0
- data/doc/GandiV5/Domain/Contract.html +520 -0
- data/doc/GandiV5/Domain/Dates.html +1313 -0
- data/doc/GandiV5/Domain/RenewalInformation.html +1147 -0
- data/doc/GandiV5/Domain/RestoreInformation.html +339 -0
- data/doc/GandiV5/Domain/SharingSpace.html +437 -0
- data/doc/GandiV5/Domain/TLD.html +1565 -0
- data/doc/GandiV5/Domain.html +16847 -0
- data/doc/GandiV5/Email/Mailbox/Responder.html +1560 -0
- data/doc/GandiV5/Email/Mailbox.html +6307 -0
- data/doc/GandiV5/Email/Offer.html +514 -0
- data/doc/GandiV5/Email/Slot.html +4244 -0
- data/doc/GandiV5/Email.html +144 -0
- data/doc/GandiV5/Error/GandiError.html +270 -0
- data/doc/GandiV5/Error.html +151 -0
- data/doc/GandiV5/LiveDNS/Domain.html +2984 -0
- data/doc/GandiV5/LiveDNS/RecordSet.html +1593 -0
- data/doc/GandiV5/LiveDNS/Zone/Snapshot.html +1556 -0
- data/doc/GandiV5/LiveDNS/Zone.html +8891 -0
- data/doc/GandiV5/LiveDNS.html +300 -0
- data/doc/GandiV5/Organization.html +2341 -0
- data/doc/GandiV5.html +1183 -0
- data/doc/_index.html +474 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +496 -0
- data/doc/file.README.html +175 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +175 -0
- data/doc/js/app.js +303 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +2427 -0
- data/doc/top-level-namespace.html +110 -0
- data/gandi_v5.gemspec +1 -1
- data/lib/gandi_v5/billing.rb +2 -2
- data/lib/gandi_v5/data.rb +2 -0
- data/lib/gandi_v5/domain/auto_renew.rb +4 -4
- 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/product.rb +52 -0
- data/lib/gandi_v5/domain/availability/tax.rb +20 -0
- data/lib/gandi_v5/domain/availability.rb +49 -0
- data/lib/gandi_v5/domain/tld.rb +57 -0
- data/lib/gandi_v5/domain.rb +41 -86
- data/lib/gandi_v5/email/mailbox/responder.rb +43 -2
- data/lib/gandi_v5/email/mailbox.rb +32 -21
- data/lib/gandi_v5/email/offer.rb +2 -2
- data/lib/gandi_v5/email/slot.rb +42 -16
- data/lib/gandi_v5/error/gandi_error.rb +2 -2
- data/lib/gandi_v5/live_dns/domain.rb +59 -45
- data/lib/gandi_v5/live_dns/zone/snapshot.rb +27 -8
- data/lib/gandi_v5/live_dns/zone.rb +63 -59
- data/lib/gandi_v5/live_dns.rb +20 -0
- data/lib/gandi_v5/organization.rb +2 -2
- data/lib/gandi_v5/version.rb +1 -1
- data/lib/gandi_v5.rb +25 -5
- data/spec/features/domain_spec.rb +1 -1
- data/spec/fixtures/bodies/{GandiV5_Domain/availability.yaml → GandiV5_Domain_Availability/fetch.yaml} +0 -0
- data/spec/fixtures/bodies/{GandiV5_Domain/tld.yaml → GandiV5_Domain_TLD/fetch.yaml} +0 -0
- data/spec/fixtures/bodies/{GandiV5_Domain/tlds.yaml → GandiV5_Domain_TLD/list.yaml} +0 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/{get.yaml → fetch.yaml} +0 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/list.yaml +3 -0
- data/spec/units/gandi_v5/billing_spec.rb +2 -2
- 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/tld_spec.rb +29 -0
- data/spec/units/gandi_v5/domain_spec.rb +89 -81
- data/spec/units/gandi_v5/email/mailbox/responder_spec.rb +52 -0
- data/spec/units/gandi_v5/email/mailbox_spec.rb +56 -27
- data/spec/units/gandi_v5/email/offer_spec.rb +1 -1
- data/spec/units/gandi_v5/email/slot_spec.rb +101 -13
- data/spec/units/gandi_v5/live_dns/domain_spec.rb +70 -40
- data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +32 -3
- data/spec/units/gandi_v5/live_dns/zone_spec.rb +68 -50
- data/spec/units/gandi_v5/live_dns_spec.rb +24 -0
- data/spec/units/gandi_v5/organization_spec.rb +1 -1
- data/spec/units/gandi_v5_spec.rb +37 -12
- metadata +72 -9
- data/TODO.md +0 -29
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# TODO: Allow enable/disable from here too ???
|
4
|
-
|
5
3
|
class GandiV5
|
6
4
|
class Email
|
7
5
|
class Mailbox
|
@@ -15,13 +13,26 @@ class GandiV5
|
|
15
13
|
# @return [nil, Time]
|
16
14
|
# @!attribute [r] message
|
17
15
|
# @return [nil, String]
|
16
|
+
# @!attribute [r] mailbox
|
17
|
+
# @return [GandiV5::Email::Mailbox] the mailbox this repsonder belongs to.
|
18
18
|
class Responder
|
19
19
|
include GandiV5::Data
|
20
20
|
|
21
|
+
attr_reader :mailbox
|
22
|
+
|
21
23
|
members :enabled, :message
|
22
24
|
member :starts_at, converter: GandiV5::Data::Converter::Time
|
23
25
|
member :ends_at, converter: GandiV5::Data::Converter::Time
|
24
26
|
|
27
|
+
# Create a new GandiV5::Email::Mailbox::Responder
|
28
|
+
# @param mailbox [GandiV5::Email::Mailbox] the mailbox this responder belongs to.
|
29
|
+
# @param members [Hash<Symbol => Object>]
|
30
|
+
# @return [GandiV5::Email::Slot]
|
31
|
+
def initialize(mailbox: nil, **members)
|
32
|
+
super(**members)
|
33
|
+
@mailbox = mailbox
|
34
|
+
end
|
35
|
+
|
25
36
|
# Check if this responder is currently active.
|
26
37
|
# @return [Boolean] whether the responder is enabled,
|
27
38
|
# started in the past and ends in the future.
|
@@ -30,6 +41,36 @@ class GandiV5
|
|
30
41
|
(starts_at.nil? || starts_at < Time.now) &&
|
31
42
|
(ends_at.nil? || ends_at > Time.now)
|
32
43
|
end
|
44
|
+
|
45
|
+
# Enable the auto responder in Gandi.
|
46
|
+
# @param message [String]
|
47
|
+
# @param starts_at [Time]
|
48
|
+
# @param ends_at [Time]
|
49
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
50
|
+
def enable(message:, ends_at:, starts_at: Time.now)
|
51
|
+
mailbox.update responder: {
|
52
|
+
message: message,
|
53
|
+
starts_at: GandiV5::Data::Converter::Time.to_gandi(starts_at),
|
54
|
+
ends_at: GandiV5::Data::Converter::Time.to_gandi(ends_at),
|
55
|
+
enabled: true
|
56
|
+
}
|
57
|
+
|
58
|
+
self.starts_at = starts_at
|
59
|
+
self.ends_at = ends_at
|
60
|
+
self.message = message
|
61
|
+
self.enabled = true
|
62
|
+
end
|
63
|
+
|
64
|
+
# Disable the auto responder in Gandi.
|
65
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
66
|
+
def disable
|
67
|
+
mailbox.update responder: { enabled: false }
|
68
|
+
|
69
|
+
self.starts_at = nil
|
70
|
+
self.ends_at = nil
|
71
|
+
self.message = nil
|
72
|
+
self.enabled = false
|
73
|
+
end
|
33
74
|
end
|
34
75
|
end
|
35
76
|
end
|
@@ -44,33 +44,43 @@ class GandiV5
|
|
44
44
|
|
45
45
|
alias mailbox_uuid uuid
|
46
46
|
|
47
|
+
# Create a new GandiV5::Email::Mailbox
|
48
|
+
# @param members [Hash<Symbol => Object>]
|
49
|
+
# @return [GandiV5::Email::Slot]
|
50
|
+
def initialize(**members)
|
51
|
+
super(**members)
|
52
|
+
responder.instance_exec(self) { |mb| @mailbox = mb } if responder?
|
53
|
+
end
|
54
|
+
|
47
55
|
# Delete the mailbox and it's contents.
|
48
56
|
# If you delete a mailbox for which you have purchased a slot,
|
49
57
|
# this action frees the slot so it once again becomes available
|
50
58
|
# for use with a new mailbox, or for deletion.
|
51
59
|
# @see https://api.gandi.net/docs/email#delete-v5-email-mailboxes-domain-mailbox_id
|
52
60
|
# @return [String] The confirmation message from Gandi.
|
53
|
-
# @raise [GandiV5::Error::GandiError
|
61
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
54
62
|
def delete
|
55
|
-
data = GandiV5.delete url
|
63
|
+
_response, data = GandiV5.delete url
|
56
64
|
data['message']
|
57
65
|
end
|
58
66
|
|
59
67
|
# Purge the contents of the mailbox.
|
60
68
|
# @see https://api.gandi.net/docs/email#delete-v5-email-mailboxes-domain-mailbox_id-contents
|
61
69
|
# @return [String] The confirmation message from Gandi.
|
62
|
-
# @raise [GandiV5::Error::GandiError
|
70
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
63
71
|
def purge
|
64
|
-
data = GandiV5.delete "#{url}/contents"
|
72
|
+
_response, data = GandiV5.delete "#{url}/contents"
|
65
73
|
data['message']
|
66
74
|
end
|
67
75
|
|
68
76
|
# Requery Gandi fo this mailbox's information.
|
69
77
|
# @return [GandiV5::Email::Mailbox]
|
70
|
-
# @raise [GandiV5::Error::GandiError
|
78
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
71
79
|
def refresh
|
72
|
-
data = GandiV5.get url
|
80
|
+
_response, data = GandiV5.get url
|
73
81
|
from_gandi data
|
82
|
+
responder.instance_exec(self) { |mb| @mailbox = mb } if responder?
|
83
|
+
self
|
74
84
|
end
|
75
85
|
|
76
86
|
# Update the mailbox's settings.
|
@@ -81,8 +91,7 @@ class GandiV5
|
|
81
91
|
# @param responder [Hash, GandiV5::Mailbox::Responder, #to_gandi, #to_h]
|
82
92
|
# auto responder settings.
|
83
93
|
# @return [String] The confirmation message from Gandi.
|
84
|
-
# @raise [GandiV5::Error::GandiError
|
85
|
-
# rubocop:disable Metrics/AbcSize
|
94
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
86
95
|
def update(**body)
|
87
96
|
return 'Nothing to update.' if body.empty?
|
88
97
|
|
@@ -93,11 +102,10 @@ class GandiV5
|
|
93
102
|
body[:responder] = responder.respond_to?(:to_gandi) ? responder.to_gandi : responder.to_h
|
94
103
|
end
|
95
104
|
|
96
|
-
data = GandiV5.patch url, body.to_json
|
105
|
+
_response, data = GandiV5.patch url, body.to_json
|
97
106
|
refresh
|
98
107
|
data['message']
|
99
108
|
end
|
100
|
-
# rubocop:enable Metrics/AbcSize
|
101
109
|
|
102
110
|
# Create a new mailbox.
|
103
111
|
# Note that before you can create a mailbox, you must have a slot available.
|
@@ -107,13 +115,16 @@ class GandiV5
|
|
107
115
|
# @param password [String, #to_s] the password to use.
|
108
116
|
# @param aliases [Array<String, #to_s>] any alternative email address to be used.
|
109
117
|
# @param type [:standard, :premium] the type of mailbox slot to use.
|
110
|
-
# @return [
|
111
|
-
# @raise [GandiV5::Error
|
112
|
-
#
|
118
|
+
# @return [GandiV5::Email::Mailbox] The created mailbox.
|
119
|
+
# @raise [GandiV5::Error] if no slots are available.
|
120
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
113
121
|
def self.create(fqdn, login, password, aliases: [], type: :standard)
|
114
|
-
#
|
122
|
+
fail ArgumentError, "#{type.inspect} is not a valid type" unless TYPES.include?(type)
|
123
|
+
if GandiV5::Email::Slot.list.none? { |slot| slot.mailbox_type == type && slot.inactive? }
|
124
|
+
fail GandiV5::Error, "no available #{type} slots"
|
125
|
+
end
|
126
|
+
|
115
127
|
check_password password
|
116
|
-
# TODO: Check if a slot is available
|
117
128
|
|
118
129
|
body = {
|
119
130
|
mailbox_type: type,
|
@@ -122,8 +133,8 @@ class GandiV5
|
|
122
133
|
aliases: aliases.push
|
123
134
|
}.to_json
|
124
135
|
|
125
|
-
|
126
|
-
|
136
|
+
response, _data = GandiV5.post url(fqdn), body
|
137
|
+
fetch fqdn, response.headers[:location].split('/').last
|
127
138
|
end
|
128
139
|
|
129
140
|
# Get information for a mailbox.
|
@@ -131,9 +142,9 @@ class GandiV5
|
|
131
142
|
# @param fqdn [String, #to_s] the fully qualified domain name for the mailbox.
|
132
143
|
# @param uuid [String, #to_s] unique identifier of the mailbox.
|
133
144
|
# @return [GandiV5::Email::Mailbox]
|
134
|
-
# @raise [GandiV5::Error::GandiError
|
145
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
135
146
|
def self.fetch(fqdn, uuid)
|
136
|
-
data = GandiV5.get url(fqdn, uuid)
|
147
|
+
_response, data = GandiV5.get url(fqdn, uuid)
|
137
148
|
from_gandi data
|
138
149
|
end
|
139
150
|
|
@@ -149,7 +160,7 @@ class GandiV5
|
|
149
160
|
# @param login [String] (optional) filter the list by login (pattern)
|
150
161
|
# e.g. ("alice" "*lice", "alic*").
|
151
162
|
# @return [Array<GandiV5::Email::Mailbox>]
|
152
|
-
# @raise [GandiV5::Error::GandiError
|
163
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
153
164
|
def self.list(fqdn, page: (1..), **params)
|
154
165
|
page = [page.to_i] unless page.respond_to?(:each)
|
155
166
|
|
@@ -158,7 +169,7 @@ class GandiV5
|
|
158
169
|
|
159
170
|
mailboxes = []
|
160
171
|
page.each do |page_number|
|
161
|
-
data = GandiV5.get url(fqdn), params: params.merge(page: page_number)
|
172
|
+
_response, data = GandiV5.get url(fqdn), params: params.merge(page: page_number)
|
162
173
|
break if data.empty?
|
163
174
|
|
164
175
|
mailboxes += data.map { |mailbox| from_gandi mailbox }
|
data/lib/gandi_v5/email/offer.rb
CHANGED
@@ -17,9 +17,9 @@ class GandiV5
|
|
17
17
|
# @see https://api.gandi.net/docs/email#get-v5-email-offers-domain
|
18
18
|
# @param fqdn [String, #to_s] the fully qualified domain name to get the offer for.
|
19
19
|
# @return [GandiV5::Email::Offer]
|
20
|
-
# @raise [GandiV5::Error::GandiError
|
20
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
21
21
|
def self.fetch(fqdn)
|
22
|
-
data = GandiV5.get "#{BASE}email/offers/#{CGI.escape fqdn}"
|
22
|
+
_response, data = GandiV5.get "#{BASE}email/offers/#{CGI.escape fqdn}"
|
23
23
|
from_gandi data
|
24
24
|
end
|
25
25
|
end
|
data/lib/gandi_v5/email/slot.rb
CHANGED
@@ -39,12 +39,12 @@ class GandiV5
|
|
39
39
|
alias slot_id id
|
40
40
|
|
41
41
|
# Create a new GandiV5::Email::Slot
|
42
|
-
# @param
|
42
|
+
# @param fqdn [String] the fully qualified domain this slot belongs to.
|
43
43
|
# @param members [Hash<Symbol => Object>]
|
44
44
|
# @return [GandiV5::Email::Slot]
|
45
45
|
def initialize(fqdn: nil, **members)
|
46
46
|
super(**members)
|
47
|
-
@fqdn = fqdn
|
47
|
+
@fqdn = fqdn
|
48
48
|
end
|
49
49
|
|
50
50
|
# Delete this slot if it is inactive and refundable.
|
@@ -53,20 +53,23 @@ class GandiV5
|
|
53
53
|
# @see GandiV5::Email::Mailbox#delete
|
54
54
|
# @see https://api.gandi.net/docs/email#delete-v5-email-slots-domain-slot_id
|
55
55
|
# @return [String] The confirmation message from Gandi.
|
56
|
-
# @raise [GandiV5::Error
|
57
|
-
#
|
58
|
-
#
|
56
|
+
# @raise [GandiV5::Error] if slot is active.
|
57
|
+
# @raise [GandiV5::Error] if slot is not refundable.
|
58
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
59
59
|
def delete
|
60
|
-
|
60
|
+
fail GandiV5::Error, 'slot can\'t be deleted whilst active' if active?
|
61
|
+
fail GandiV5::Error, 'slot can\'t be deleted if it\'s not refundable' unless refundable
|
62
|
+
|
63
|
+
_response, data = GandiV5.delete url
|
61
64
|
data['message']
|
62
65
|
end
|
63
66
|
|
64
67
|
# Requery Gandi for this slot's information.
|
65
68
|
# @see https://api.gandi.net/docs/email#get-v5-email-slots-domain-slot_id
|
66
69
|
# @return [GandiV5::Email::Slot]
|
67
|
-
# @raise [GandiV5::Error::GandiError
|
70
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
68
71
|
def refresh
|
69
|
-
data = GandiV5.get url
|
72
|
+
_response, data = GandiV5.get url
|
70
73
|
from_gandi data
|
71
74
|
end
|
72
75
|
|
@@ -77,15 +80,14 @@ class GandiV5
|
|
77
80
|
# @param fqdn [String, #to_s] the fully qualified domain name to add the slot to.
|
78
81
|
# @param type [:standard, :premium] Tyhe type of slot to add.
|
79
82
|
# @return [String] The confirmation message from Gandi.
|
80
|
-
# @raise [GandiV5::Error::GandiError
|
81
|
-
# TODO: Fetch created slot
|
83
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
82
84
|
def self.create(fqdn, type = :standard)
|
83
85
|
body = {
|
84
86
|
mailbox_type: type
|
85
87
|
}.to_json
|
86
88
|
|
87
|
-
|
88
|
-
|
89
|
+
response, _data = GandiV5.post url(fqdn), body
|
90
|
+
fetch fqdn, response.headers[:location].split('/').last
|
89
91
|
end
|
90
92
|
|
91
93
|
# Get information for a slot.
|
@@ -93,9 +95,9 @@ class GandiV5
|
|
93
95
|
# @param fqdn [String, #to_s] the fully qualified domain name the slot is on.
|
94
96
|
# @param id [String, #to_s] the ID of the slot to fetch.
|
95
97
|
# @return [GandiV5::Email::Slot]
|
96
|
-
# @raise [GandiV5::Error::GandiError
|
98
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
97
99
|
def self.fetch(fqdn, id)
|
98
|
-
data = GandiV5.get url(fqdn, id)
|
100
|
+
_response, data = GandiV5.get url(fqdn, id)
|
99
101
|
slot = from_gandi data
|
100
102
|
slot.instance_eval { @fqdn = fqdn }
|
101
103
|
slot
|
@@ -105,9 +107,9 @@ class GandiV5
|
|
105
107
|
# @see https://api.gandi.net/docs/email#
|
106
108
|
# @param fqdn [String, #to_s] the fully qualified domain name to list slots for.
|
107
109
|
# @return [Array<GandiV5::Email::Slot>]
|
108
|
-
# @raise [GandiV5::Error::GandiError
|
110
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
109
111
|
def self.list(fqdn)
|
110
|
-
data = GandiV5.get url(fqdn)
|
112
|
+
_response, data = GandiV5.get url(fqdn)
|
111
113
|
data.map { |item| from_gandi item }
|
112
114
|
.each { |item| item.instance_eval { @fqdn = fqdn } }
|
113
115
|
end
|
@@ -118,6 +120,30 @@ class GandiV5
|
|
118
120
|
status.eql?(:active)
|
119
121
|
end
|
120
122
|
|
123
|
+
# Check if the slot is inactive (not in use)
|
124
|
+
# @return [Boolean]
|
125
|
+
def inactive?
|
126
|
+
status.eql?(:inactive)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Check if the slot's mailbox_type is :free
|
130
|
+
# @return [Boolean]
|
131
|
+
def free?
|
132
|
+
mailbox_type.eql?(:free)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Check if the slot's mailbox_type is :standard
|
136
|
+
# @return [Boolean]
|
137
|
+
def standard?
|
138
|
+
mailbox_type.eql?(:standard)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Check if the slot's mailbox_type is :premium
|
142
|
+
# @return [Boolean]
|
143
|
+
def premium?
|
144
|
+
mailbox_type.eql?(:premium)
|
145
|
+
end
|
146
|
+
|
121
147
|
private
|
122
148
|
|
123
149
|
def url
|
@@ -4,9 +4,9 @@ class GandiV5
|
|
4
4
|
class Error < RuntimeError
|
5
5
|
# Generic error class for errors returned by Gandi.
|
6
6
|
class GandiError < GandiV5::Error
|
7
|
-
# Generate a new GandiV5::Error::GandiError
|
7
|
+
# Generate a new GandiV5::Error::GandiError from the hash returned by Gandi.
|
8
8
|
# @param hash [Hash] the hash returned by Gandi.
|
9
|
-
# @return [GandiV5::Error::GandiError
|
9
|
+
# @return [GandiV5::Error::GandiError]
|
10
10
|
def self.from_hash(hash)
|
11
11
|
hash['errors'] ||= []
|
12
12
|
|
@@ -20,9 +20,9 @@ class GandiV5
|
|
20
20
|
|
21
21
|
# Refetch the information for this domain from Gandi.
|
22
22
|
# @return [GandiV5::LiveDNS::Domain]
|
23
|
-
# @raise [GandiV5::Error::GandiError
|
23
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
24
24
|
def refresh
|
25
|
-
data = GandiV5.get url
|
25
|
+
_response, data = GandiV5.get url
|
26
26
|
from_gandi data
|
27
27
|
end
|
28
28
|
|
@@ -36,7 +36,7 @@ class GandiV5
|
|
36
36
|
# @param name [String] the name to fetch records for.
|
37
37
|
# @param type [String] the record type to fetch.
|
38
38
|
# @return [Array<GandiV5::LiveDNS::RecordSet>]
|
39
|
-
# @raise [GandiV5::Error::GandiError
|
39
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
40
40
|
def fetch_records(name = nil, type = nil)
|
41
41
|
GandiV5::LiveDNS.require_valid_record_type type if type
|
42
42
|
|
@@ -44,7 +44,7 @@ class GandiV5
|
|
44
44
|
url_ += "/#{CGI.escape name}" if name
|
45
45
|
url_ += "/#{CGI.escape type}" if type
|
46
46
|
|
47
|
-
data = GandiV5.get url_
|
47
|
+
_response, data = GandiV5.get url_
|
48
48
|
data = [data] unless data.is_a?(Array)
|
49
49
|
data.map { |item| GandiV5::LiveDNS::RecordSet.from_gandi item }
|
50
50
|
end
|
@@ -59,7 +59,7 @@ class GandiV5
|
|
59
59
|
# @param name [String] the name to fetch records for.
|
60
60
|
# @param type [String] the record type to fetch.
|
61
61
|
# @return [String]
|
62
|
-
# @raise [GandiV5::Error::GandiError
|
62
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
63
63
|
def fetch_zone_lines(name = nil, type = nil)
|
64
64
|
GandiV5::LiveDNS.require_valid_record_type type if type
|
65
65
|
|
@@ -67,7 +67,7 @@ class GandiV5
|
|
67
67
|
url_ += "/#{CGI.escape name}" if name
|
68
68
|
url_ += "/#{CGI.escape type}" if type
|
69
69
|
|
70
|
-
GandiV5.get
|
70
|
+
GandiV5.get(url_, accept: 'text/plain').last
|
71
71
|
end
|
72
72
|
|
73
73
|
# Add record to this domain.
|
@@ -76,7 +76,7 @@ class GandiV5
|
|
76
76
|
# @param ttl [Integer]
|
77
77
|
# @param values [Array<String>]
|
78
78
|
# @return [String] The confirmation message from Gandi.
|
79
|
-
# @raise [GandiV5::Error::GandiError
|
79
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
80
80
|
def add_record(name, type, ttl, *values)
|
81
81
|
GandiV5::LiveDNS.require_valid_record_type type
|
82
82
|
fail ArgumentError, 'ttl must be positive and non-zero' unless ttl.positive?
|
@@ -88,7 +88,7 @@ class GandiV5
|
|
88
88
|
rrset_ttl: ttl,
|
89
89
|
rrset_values: values
|
90
90
|
}.to_json
|
91
|
-
data = GandiV5.post "#{url}/records", body
|
91
|
+
_response, data = GandiV5.post "#{url}/records", body
|
92
92
|
data['message']
|
93
93
|
end
|
94
94
|
|
@@ -102,14 +102,14 @@ class GandiV5
|
|
102
102
|
# @param name [String] the name to delete records for.
|
103
103
|
# @param type [String] the record type to delete.
|
104
104
|
# @return [nil]
|
105
|
-
# @raise [GandiV5::Error::GandiError
|
105
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
106
106
|
def delete_records(name = nil, type = nil)
|
107
107
|
GandiV5::LiveDNS.require_valid_record_type(type) if type
|
108
108
|
|
109
109
|
url_ = "#{url}/records"
|
110
110
|
url_ += "/#{CGI.escape name}" if name
|
111
111
|
url_ += "/#{CGI.escape type}" if type
|
112
|
-
GandiV5.delete
|
112
|
+
GandiV5.delete(url_).last
|
113
113
|
end
|
114
114
|
|
115
115
|
# Replace all records for this domain.
|
@@ -119,7 +119,7 @@ class GandiV5
|
|
119
119
|
# @param text [String] zone file lines to replace the records with.
|
120
120
|
# @return [String] The confirmation message from Gandi.
|
121
121
|
# @raise [ArgumentError] if neither/both of records & test are passed.
|
122
|
-
# @raise [GandiV5::Error::GandiError
|
122
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
123
123
|
def replace_records(records: nil, text: nil)
|
124
124
|
unless [records, text].count(&:nil?).eql?(1)
|
125
125
|
fail ArgumentError, 'you must pass ONE of records: or text:'
|
@@ -129,70 +129,84 @@ class GandiV5
|
|
129
129
|
body = {
|
130
130
|
items: records.map { |r| r.transform_keys { |k| "rrset_#{k}" } }
|
131
131
|
}.to_json
|
132
|
-
data = GandiV5.put "#{url}/records", body
|
132
|
+
_response, data = GandiV5.put "#{url}/records", body
|
133
133
|
elsif text
|
134
|
-
data = GandiV5.put "#{url}/records", text, 'content-type': 'text/plain'
|
134
|
+
_response, data = GandiV5.put "#{url}/records", text, 'content-type': 'text/plain'
|
135
135
|
end
|
136
136
|
data['message']
|
137
137
|
end
|
138
138
|
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
139
|
+
# @override replace_records_for(name, records)
|
140
|
+
# Replace records for a name in this domain.
|
141
|
+
# @param name [String]
|
142
|
+
# @param records
|
143
|
+
# [Array<Hash<type: String, ttl: Integer, values: Array<String>>>]
|
144
|
+
# the records to add.
|
145
|
+
# @override replace_records_for(name, values, type: nil, ttl: nil)
|
146
|
+
# Replace records for a name in this domain.
|
147
|
+
# @param name [String]
|
148
|
+
# @param type [String] the record type.
|
149
|
+
# @param ttl [Integer] the TTL to set for the record.
|
150
|
+
# @param values [Array<String>] the values to set for the record.
|
151
|
+
# @raise [ArgumentError] if ttl is present and type is absent.
|
144
152
|
# @return [String] The confirmation message from Gandi.
|
145
|
-
# @raise [GandiV5::Error::GandiError
|
146
|
-
def replace_records_for(name,
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
154
|
+
def replace_records_for(name, records, type: nil, ttl: nil)
|
155
|
+
fail ArgumentError, 'missing keyword: type' if ttl && type.nil?
|
156
|
+
|
157
|
+
if type
|
158
|
+
GandiV5::LiveDNS.require_valid_record_type type
|
159
|
+
body = { rrset_values: records, rrset_ttl: ttl }
|
160
|
+
# body[:rrset_ttl] = ttl if ttl
|
161
|
+
_response, data = GandiV5.put "#{url}/records/#{name}/#{type}", body.to_json
|
153
162
|
|
154
|
-
|
155
|
-
# Replace records of a given type for a name in this domain.
|
156
|
-
# TODO: @param name [Type] description.
|
157
|
-
# TODO: @param ttl [Type] description.
|
158
|
-
# TODO: documentation for *values
|
159
|
-
# @return [String] The confirmation message from Gandi.
|
160
|
-
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
161
|
-
define_method "replace_#{type.downcase}_records_for" do |name, ttl, *values|
|
163
|
+
else
|
162
164
|
body = {
|
163
|
-
|
164
|
-
|
165
|
-
}.to_json
|
166
|
-
data = GandiV5.put "#{url}/records/#{name}/#{type}", body
|
167
|
-
data['message']
|
165
|
+
items: records.map { |r| r.transform_keys { |k| "rrset_#{k}" } }
|
166
|
+
}
|
167
|
+
_response, data = GandiV5.put "#{url}/records/#{name}", body.to_json
|
168
168
|
end
|
169
|
+
|
170
|
+
data['message']
|
169
171
|
end
|
170
172
|
|
171
173
|
# Change the zone used by this domain.
|
172
174
|
# @param uuid [String, #uuid, #to_s] the UUID of the zone this domain should now use.
|
173
175
|
# @return [String] The confirmation message from Gandi.
|
174
|
-
# @raise [GandiV5::Error::GandiError
|
176
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
175
177
|
def change_zone(uuid)
|
176
178
|
uuid = uuid.uuid if uuid.respond_to?(:uuid)
|
177
|
-
data = GandiV5.patch url, { zone_uuid: uuid }.to_json
|
179
|
+
_response, data = GandiV5.patch url, { zone_uuid: uuid }.to_json
|
178
180
|
self.zone_uuid = uuid
|
179
181
|
data['message']
|
180
182
|
end
|
181
183
|
|
184
|
+
# @see GandiV5::LiveDNS::Zone.fetch
|
185
|
+
def fetch_zone
|
186
|
+
GandiV5::LiveDNS::Zone.fetch zone_uuid
|
187
|
+
end
|
188
|
+
|
189
|
+
# The domain's zone (fetching from Gandi if required).
|
190
|
+
# @return [GandiV5::LiveDNS::Zone]
|
191
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
192
|
+
def zone
|
193
|
+
@zone ||= fetch_zone
|
194
|
+
end
|
195
|
+
|
182
196
|
# List the domains.
|
183
197
|
# @return [Array<GandiV5::LiveDNS::Domain>]
|
184
|
-
# @raise [GandiV5::Error::GandiError
|
198
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
185
199
|
def self.list
|
186
|
-
data = GandiV5.get url
|
200
|
+
_response, data = GandiV5.get url
|
187
201
|
data.map { |item| from_gandi item }
|
188
202
|
end
|
189
203
|
|
190
204
|
# Get a domain.
|
191
205
|
# @param fqdn [String, #to_s] the fully qualified domain name to fetch.
|
192
206
|
# @return [GandiV5::LiveDNS::Domain]
|
193
|
-
# @raise [GandiV5::Error::GandiError
|
207
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
194
208
|
def self.fetch(fqdn)
|
195
|
-
data = GandiV5.get url(fqdn)
|
209
|
+
_response, data = GandiV5.get url(fqdn)
|
196
210
|
from_gandi data
|
197
211
|
end
|
198
212
|
|
@@ -28,32 +28,51 @@ class GandiV5
|
|
28
28
|
|
29
29
|
# Delete this snapshot.
|
30
30
|
# @return [String] The confirmation message from Gandi.
|
31
|
-
# @raise [GandiV5::Error::GandiError
|
31
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
32
32
|
def delete
|
33
|
-
data = GandiV5.delete url
|
33
|
+
_response, data = GandiV5.delete url
|
34
34
|
data['message']
|
35
35
|
end
|
36
36
|
|
37
|
+
# @see GandiV5::LiveDNS::Zone.fetch
|
38
|
+
def fetch_zone
|
39
|
+
GandiV5::LiveDNS::Zone.fetch zone_uuid
|
40
|
+
end
|
41
|
+
|
42
|
+
# The snapshot's zone (fetching from Gandi if required).
|
43
|
+
# @return [GandiV5::LiveDNS::Zone]
|
44
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
45
|
+
def zone
|
46
|
+
@zone ||= fetch_zone
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get snapshot UUIDs for this zone from Gandi.
|
50
|
+
# @return [Hash{String => Time}] Mapping UUID to time made.
|
51
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
52
|
+
def self.list(zone_uuid)
|
53
|
+
_response, data = GandiV5.get url(zone_uuid)
|
54
|
+
Hash[data.map { |snapshot| [snapshot['uuid'], Time.parse(snapshot['date_created'])] }]
|
55
|
+
end
|
56
|
+
|
37
57
|
# Get snapshot from Gandi.
|
38
58
|
# @param zone_uuid [String, #to_s] the UUID of the zone the snapshot was made of.
|
39
59
|
# @param snapshot_uuid [String, #to_s] the UUID of the snapshot to fetch.
|
40
60
|
# @return [GandiV5::LiveDNS::Zone::Snapshot]
|
41
|
-
# @raise [GandiV5::Error::GandiError
|
61
|
+
# @raise [GandiV5::Error::GandiError] if Gandi returns an error.
|
42
62
|
def self.fetch(zone_uuid, snapshot_uuid)
|
43
|
-
data = GandiV5.get url(zone_uuid, snapshot_uuid)
|
63
|
+
_response, data = GandiV5.get url(zone_uuid, snapshot_uuid)
|
44
64
|
from_gandi data
|
45
65
|
end
|
46
66
|
|
47
|
-
# TODO: Move listing snapshots to here
|
48
|
-
|
49
67
|
private
|
50
68
|
|
51
69
|
def url
|
52
70
|
"#{BASE}zones/#{CGI.escape zone_uuid}/snapshots/#{CGI.escape uuid}"
|
53
71
|
end
|
54
72
|
|
55
|
-
def self.url(zone_uuid, snapshot_uuid)
|
56
|
-
"#{BASE}zones/#{CGI.escape zone_uuid}/snapshots
|
73
|
+
def self.url(zone_uuid, snapshot_uuid = nil)
|
74
|
+
"#{BASE}zones/#{CGI.escape zone_uuid}/snapshots" +
|
75
|
+
(snapshot_uuid ? "/#{CGI.escape snapshot_uuid}" : '')
|
57
76
|
end
|
58
77
|
private_class_method :url
|
59
78
|
end
|