gandi_v5 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|