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,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class LiveDNS
|
5
|
+
# A record set which comes from either a domain or zone.
|
6
|
+
# @!attribute [r] type
|
7
|
+
# @return [String]
|
8
|
+
# @!attribute [r] ttl
|
9
|
+
# @return [Integer]
|
10
|
+
# @!attribute [r] name
|
11
|
+
# @return [String]
|
12
|
+
# @!attribute [r] values
|
13
|
+
# @return [Array<String>]
|
14
|
+
class RecordSet
|
15
|
+
include GandiV5::Data
|
16
|
+
|
17
|
+
member :type, gandi_key: 'rrset_type'
|
18
|
+
member :ttl, gandi_key: 'rrset_ttl'
|
19
|
+
member :name, gandi_key: 'rrset_name'
|
20
|
+
member :values, gandi_key: 'rrset_values'
|
21
|
+
|
22
|
+
# Generate zone file lines for the record.
|
23
|
+
# @return [String]
|
24
|
+
def to_s
|
25
|
+
values.map do |value|
|
26
|
+
"#{name}\t#{ttl}\tIN\t#{type}\t#{value}"
|
27
|
+
end.join("\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
GandiV5::LiveDNS::RECORD_TYPES.each do |t|
|
31
|
+
# Check the record type.
|
32
|
+
# @return [Boolean]
|
33
|
+
define_method "#{t.downcase}?" do
|
34
|
+
type.eql?(t)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Check the TTL's value in seconds.
|
39
|
+
# @param number [Integer] the number of second(s) to check against.
|
40
|
+
# @return [Boolean]
|
41
|
+
def second?(number = 1)
|
42
|
+
ttl == number
|
43
|
+
end
|
44
|
+
alias seconds? second?
|
45
|
+
|
46
|
+
# Check the TTL's value in minutes.
|
47
|
+
# @param number [Integer] the number of minute(s) to check against.
|
48
|
+
# @return [Boolean]
|
49
|
+
def minute?(number = 1)
|
50
|
+
ttl == number * 60
|
51
|
+
end
|
52
|
+
alias minutes? minute?
|
53
|
+
|
54
|
+
# Check the TTL's value in hours.
|
55
|
+
# @param number [Integer] the number of hour(s) to check against.
|
56
|
+
# @return [Boolean]
|
57
|
+
def hour?(number = 1)
|
58
|
+
ttl == number * 3_600
|
59
|
+
end
|
60
|
+
alias hours? hour?
|
61
|
+
|
62
|
+
# Check the TTL's value in days.
|
63
|
+
# @param number [Integer] the number of day(s) to check against.
|
64
|
+
# @return [Boolean]
|
65
|
+
def day?(number = 1)
|
66
|
+
ttl == number * 86_400
|
67
|
+
end
|
68
|
+
alias days? day?
|
69
|
+
|
70
|
+
# Check the TTL's value in weeks.
|
71
|
+
# @param number [Integer] the number of week(s) to check against.
|
72
|
+
# @return [Boolean]
|
73
|
+
def week?(number = 1)
|
74
|
+
ttl == number * 604_800
|
75
|
+
end
|
76
|
+
alias weeks? day?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GandiV5
|
4
|
+
class LiveDNS
|
5
|
+
class Zone
|
6
|
+
# A snapshot (backup) of a zone.
|
7
|
+
# @!attribute [r] uuid
|
8
|
+
# @return [String]
|
9
|
+
# @!attribute [r] zone_uuid
|
10
|
+
# @return [String]
|
11
|
+
# @!attribute [r] created_at
|
12
|
+
# @return [Time]
|
13
|
+
# @!attribute [r] records
|
14
|
+
# @return [Array<GandiV5::LiveDNS::RecordSet>]
|
15
|
+
class Snapshot
|
16
|
+
include GandiV5::Data
|
17
|
+
|
18
|
+
members :uuid, :zone_uuid
|
19
|
+
member :created_at, gandi_key: 'date_created', converter: GandiV5::Data::Converter::Time
|
20
|
+
member(
|
21
|
+
:records,
|
22
|
+
gandi_key: 'zone_data',
|
23
|
+
converter: GandiV5::LiveDNS::RecordSet,
|
24
|
+
array: true
|
25
|
+
)
|
26
|
+
|
27
|
+
alias snapshot_uuid uuid
|
28
|
+
|
29
|
+
# Delete this snapshot.
|
30
|
+
# @return [String] The confirmation message from Gandi.
|
31
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
32
|
+
def delete
|
33
|
+
data = GandiV5.delete url
|
34
|
+
data['message']
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get snapshot from Gandi.
|
38
|
+
# @param zone_uuid [String, #to_s] the UUID of the zone the snapshot was made of.
|
39
|
+
# @param snapshot_uuid [String, #to_s] the UUID of the snapshot to fetch.
|
40
|
+
# @return [GandiV5::LiveDNS::Zone::Snapshot]
|
41
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
42
|
+
def self.fetch(zone_uuid, snapshot_uuid)
|
43
|
+
data = GandiV5.get url(zone_uuid, snapshot_uuid)
|
44
|
+
from_gandi data
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO: Move listing snapshots to here
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def url
|
52
|
+
"#{BASE}zones/#{CGI.escape zone_uuid}/snapshots/#{CGI.escape uuid}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.url(zone_uuid, snapshot_uuid)
|
56
|
+
"#{BASE}zones/#{CGI.escape zone_uuid}/snapshots/#{CGI.escape snapshot_uuid}"
|
57
|
+
end
|
58
|
+
private_class_method :url
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,301 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'zone/snapshot'
|
4
|
+
|
5
|
+
class GandiV5
|
6
|
+
class LiveDNS
|
7
|
+
# A zone within the LiveDNS system.
|
8
|
+
# Zones can be used by any number of domains.
|
9
|
+
# @!attribute [r] uuid
|
10
|
+
# @return [String]
|
11
|
+
# @!attribute [r] name
|
12
|
+
# @return [String]
|
13
|
+
# @!attribute [r] sharing_uuid
|
14
|
+
# @return [String]
|
15
|
+
# @!attribute [r] soa_retry
|
16
|
+
# @return [Integer] retry period, as reported in SOA record.
|
17
|
+
# @!attribute [r] soa_minimum
|
18
|
+
# @return [Integer] minimum and negative TTL, as reported in SOA record.
|
19
|
+
# @!attribute [r] soa_refresh
|
20
|
+
# @return [Integer] refresh period, as reported in SOA record.
|
21
|
+
# @!attribute [r] soa_expire
|
22
|
+
# @return [Integer] expire period, as reported in SOA record.
|
23
|
+
# @!attribute [r] soa_serial
|
24
|
+
# @return [Integer] serial number, as reported in SOA record.
|
25
|
+
# @!attribute [r] soa_email
|
26
|
+
# @return [String] admin email address, as reported in SOA record.
|
27
|
+
# @!attribute [r] soa_primary_ns
|
28
|
+
# @return [String] primary name server, as reported in SOA record.
|
29
|
+
class Zone
|
30
|
+
include GandiV5::Data
|
31
|
+
|
32
|
+
members :uuid, :name
|
33
|
+
member :sharing_uuid, gandi_key: 'sharing_id'
|
34
|
+
member :soa_retry, gandi_key: 'retry'
|
35
|
+
member :soa_minimum, gandi_key: 'minimum'
|
36
|
+
member :soa_refresh, gandi_key: 'refresh'
|
37
|
+
member :soa_expire, gandi_key: 'expire'
|
38
|
+
member :soa_serial, gandi_key: 'serial'
|
39
|
+
member :soa_email, gandi_key: 'email'
|
40
|
+
member :soa_primary_ns, gandi_key: 'primary_ns'
|
41
|
+
|
42
|
+
alias zone_uuid uuid
|
43
|
+
|
44
|
+
# Generate SOA record for the zone
|
45
|
+
# @return [String]
|
46
|
+
def to_s
|
47
|
+
"@\tIN\tSOA\t#{soa_primary_ns} #{soa_email} (\n" \
|
48
|
+
"\t#{soa_serial}\t;Serial\n" \
|
49
|
+
"\t#{soa_refresh}\t\t;Refresh\n" \
|
50
|
+
"\t#{soa_retry}\t\t;Retry\n" \
|
51
|
+
"\t#{soa_expire}\t\t;Expire\n" \
|
52
|
+
"\t#{soa_minimum}\t\t;Minimum & Negative TTL\n" \
|
53
|
+
')'
|
54
|
+
end
|
55
|
+
|
56
|
+
# @overload fetch_records()
|
57
|
+
# Fetch all records for this zone.
|
58
|
+
# @overload fetch_records(name)
|
59
|
+
# Fetch records for a name.
|
60
|
+
# @param name [String] the name to fetch records for.
|
61
|
+
# @overload fetch_records(name, type)
|
62
|
+
# Fetch records of a type for a name.
|
63
|
+
# @param name [String] the name to fetch records for.
|
64
|
+
# @param type [String] the record type to fetch.
|
65
|
+
# @return [Array<GandiV5::LiveDNS::RecordSet>]
|
66
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
67
|
+
def fetch_records(name = nil, type = nil)
|
68
|
+
GandiV5::LiveDNS.require_valid_record_type type if type
|
69
|
+
|
70
|
+
url_ = "#{url}/records"
|
71
|
+
url_ += "/#{CGI.escape name}" if name
|
72
|
+
url_ += "/#{CGI.escape type}" if type
|
73
|
+
|
74
|
+
data = GandiV5.get url_
|
75
|
+
data = [data] unless data.is_a?(Array)
|
76
|
+
data.map { |item| GandiV5::LiveDNS::RecordSet.from_gandi item }
|
77
|
+
end
|
78
|
+
|
79
|
+
# @overload fetch_zone_lines()
|
80
|
+
# Fetch all records for this zone.
|
81
|
+
# @overload fetch_zone_lines(name)
|
82
|
+
# Fetch records for a name.
|
83
|
+
# @param name [String] the name to fetch records for.
|
84
|
+
# @overload fetch_zone_lines(name, type)
|
85
|
+
# Fetch records of a type for a name.
|
86
|
+
# @param name [String] the name to fetch records for.
|
87
|
+
# @param type [String] the record type to fetch.
|
88
|
+
# @return [String]
|
89
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
90
|
+
def fetch_zone_lines(name = nil, type = nil)
|
91
|
+
GandiV5::LiveDNS.require_valid_record_type type if type
|
92
|
+
|
93
|
+
url_ = "#{url}/records"
|
94
|
+
url_ += "/#{CGI.escape name}" if name
|
95
|
+
url_ += "/#{CGI.escape type}" if type
|
96
|
+
|
97
|
+
GandiV5.get url_, accept: 'text/plain'
|
98
|
+
end
|
99
|
+
|
100
|
+
# Add record to this zone.
|
101
|
+
# @param name [String]
|
102
|
+
# @param type [String]
|
103
|
+
# @param ttl [Integer]
|
104
|
+
# @param values [Array<String>]
|
105
|
+
# @return [String] The confirmation message from Gandi.
|
106
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
107
|
+
def add_record(name, type, ttl, *values)
|
108
|
+
GandiV5::LiveDNS.require_valid_record_type type
|
109
|
+
fail ArgumentError, 'ttl must be positive and non-zero' unless ttl.positive?
|
110
|
+
fail ArgumentError, 'there must be at least one value' if values.none?
|
111
|
+
|
112
|
+
body = {
|
113
|
+
rrset_name: name,
|
114
|
+
rrset_type: type,
|
115
|
+
rrset_ttl: ttl,
|
116
|
+
rrset_values: values
|
117
|
+
}.to_json
|
118
|
+
data = GandiV5.post "#{url}/records", body
|
119
|
+
data['message']
|
120
|
+
end
|
121
|
+
|
122
|
+
# @overload delete_records()
|
123
|
+
# Delete all records for this zone.
|
124
|
+
# @overload delete_records(name)
|
125
|
+
# Delete records for a name.
|
126
|
+
# @param name [String] the name to delete records for.
|
127
|
+
# @overload delete_records(name, type)
|
128
|
+
# Delete records of a type for a name.
|
129
|
+
# @param name [String] the name to delete records for.
|
130
|
+
# @param type [String] the record type to delete.
|
131
|
+
# @return [nil]
|
132
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
133
|
+
def delete_records(name = nil, type = nil)
|
134
|
+
GandiV5::LiveDNS.require_valid_record_type type if type
|
135
|
+
|
136
|
+
url_ = "#{url}/records"
|
137
|
+
url_ += "/#{CGI.escape name}" if name
|
138
|
+
url_ += "/#{CGI.escape type}" if type
|
139
|
+
GandiV5.delete url_
|
140
|
+
end
|
141
|
+
|
142
|
+
# Replace all records for this zone.
|
143
|
+
# @param records
|
144
|
+
# [Array<Hash<:name, :type => String, :ttl => Integer, :values => Array<String>>>]
|
145
|
+
# the records to add.
|
146
|
+
# @param text [String] zone file lines to replace the records with.
|
147
|
+
# @return [String] The confirmation message from Gandi.
|
148
|
+
# @raise [ArgumentError] if neither/both of records & test are passed.
|
149
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
150
|
+
def replace_records(records: nil, text: nil)
|
151
|
+
unless [records, text].count(&:nil?).eql?(1)
|
152
|
+
fail ArgumentError, 'you must pass ONE of records: or text:'
|
153
|
+
end
|
154
|
+
|
155
|
+
if records
|
156
|
+
body = {
|
157
|
+
items: records.map { |r| r.transform_keys { |k| "rrset_#{k}" } }
|
158
|
+
}.to_json
|
159
|
+
data = GandiV5.put "#{url}/records", body
|
160
|
+
elsif text
|
161
|
+
data = GandiV5.put "#{url}/records", text, 'content-type': 'text/plain'
|
162
|
+
end
|
163
|
+
data['message']
|
164
|
+
end
|
165
|
+
|
166
|
+
# Replace records for a name in this zone.
|
167
|
+
# @param name [String]
|
168
|
+
# @param records
|
169
|
+
# [Array<Hash<type: String, ttl: Integer, values: Array<String>>>]
|
170
|
+
# the records to add.
|
171
|
+
# @return [String] The confirmation message from Gandi.
|
172
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
173
|
+
def replace_records_for(name, *records)
|
174
|
+
body = {
|
175
|
+
items: records.map { |r| r.transform_keys { |k| "rrset_#{k}" } }
|
176
|
+
}.to_json
|
177
|
+
data = GandiV5.put "#{url}/records/#{name}", body
|
178
|
+
data['message']
|
179
|
+
end
|
180
|
+
|
181
|
+
GandiV5::LiveDNS::RECORD_TYPES.each do |type|
|
182
|
+
# Replace records of a given type for a name in this zone.
|
183
|
+
# @return [String] The confirmation message from Gandi.
|
184
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
185
|
+
define_method "replace_#{type.downcase}_records_for" do |name, ttl, *values|
|
186
|
+
body = {
|
187
|
+
rrset_ttl: ttl,
|
188
|
+
rrset_values: values
|
189
|
+
}.to_json
|
190
|
+
data = GandiV5.put "#{url}/records/#{name}/#{type}", body
|
191
|
+
data['message']
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# List the domains that use this zone.
|
196
|
+
# @return [Array<String>] The FQDNs.
|
197
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
198
|
+
def list_domains
|
199
|
+
data = GandiV5.get "#{url}/domains"
|
200
|
+
data.map { |item| item['fqdn'] }
|
201
|
+
end
|
202
|
+
|
203
|
+
# Attach domain to this zone.
|
204
|
+
# @param fqdn [String, #fqdn, #to_s] the fully qualified domain name
|
205
|
+
# that should start using this zone.
|
206
|
+
# @return [String] The confirmation message from Gandi.
|
207
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
208
|
+
def attach_domain(fqdn)
|
209
|
+
fqdn = fqdn.fqdn if fqdn.respond_to?(:fqdn)
|
210
|
+
data = GandiV5.patch "#{BASE}domains/#{CGI.escape fqdn}", { zone_uuid: uuid }.to_json
|
211
|
+
data['message']
|
212
|
+
end
|
213
|
+
|
214
|
+
# Get snapshot UUIDs for this zone from Gandi.lib/gandi_v5/domain/auto_renew.rb
|
215
|
+
# @return [Hash{String => Time}] Mapping UUID to time made.
|
216
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
217
|
+
def snapshots
|
218
|
+
data = GandiV5.get "#{url}/snapshots"
|
219
|
+
Hash[data.map { |snapshot| [snapshot['uuid'], Time.parse(snapshot['date_created'])] }]
|
220
|
+
end
|
221
|
+
|
222
|
+
# Get snapshot from Gandi.
|
223
|
+
# @param uuid [String] the UUID of the snapshot to fetch.
|
224
|
+
# @return [GandiV5::LiveDNS::Zone::Snapshot]
|
225
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
226
|
+
def snapshot(uuid)
|
227
|
+
GandiV5::LiveDNS::Zone::Snapshot.fetch self.uuid, uuid
|
228
|
+
end
|
229
|
+
|
230
|
+
# Take a snapshot of this zone.
|
231
|
+
# @return [GandiV5::LiveDNS::Zone::Snapshot]
|
232
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
233
|
+
def take_snapshot
|
234
|
+
data = GandiV5.post "#{url}/snapshots"
|
235
|
+
snapshot data['uuid']
|
236
|
+
end
|
237
|
+
|
238
|
+
# Update this zone.
|
239
|
+
# @param name [String, #to_s] new name for the zone.
|
240
|
+
# @return [String] The confirmation message from Gandi.
|
241
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
242
|
+
def update(name:)
|
243
|
+
data = GandiV5.patch url, { name: name }.to_json
|
244
|
+
self.name = name
|
245
|
+
data['message']
|
246
|
+
end
|
247
|
+
|
248
|
+
# Delete this zone from Gandi.
|
249
|
+
# @return [nil]
|
250
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
251
|
+
def delete
|
252
|
+
GandiV5.delete url
|
253
|
+
end
|
254
|
+
|
255
|
+
# Create a new zone.
|
256
|
+
# @param name [String] the name for the created zone.
|
257
|
+
# @param sharing_id [String] the UUID of the account to ceate the zone under.
|
258
|
+
# @return [String] The confirmation message from Gandi.
|
259
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
260
|
+
# TODO: Fetch created zone
|
261
|
+
def self.create(name, sharing_id: nil)
|
262
|
+
params = sharing_id ? { sharing_id: sharing_id } : {}
|
263
|
+
|
264
|
+
data = GandiV5.post(
|
265
|
+
url,
|
266
|
+
{ name: name }.to_json,
|
267
|
+
params: params
|
268
|
+
)
|
269
|
+
data['message']
|
270
|
+
end
|
271
|
+
|
272
|
+
# List the zones.
|
273
|
+
# @return [Array<GandiV5::LiveDNS::Zone>]
|
274
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
275
|
+
def self.list
|
276
|
+
data = GandiV5.get url
|
277
|
+
data.map { |item| from_gandi item }
|
278
|
+
end
|
279
|
+
|
280
|
+
# Get a zone from Gandi.
|
281
|
+
# @param uuid [String, #to_s] the UUID of the zone to fetch.
|
282
|
+
# @return [GandiV5::LiveDNS::Zone]
|
283
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
284
|
+
def self.fetch(uuid)
|
285
|
+
data = GandiV5.get url(uuid)
|
286
|
+
from_gandi data
|
287
|
+
end
|
288
|
+
|
289
|
+
private
|
290
|
+
|
291
|
+
def url
|
292
|
+
"#{BASE}zones/#{CGI.escape uuid}"
|
293
|
+
end
|
294
|
+
|
295
|
+
def self.url(uuid = nil)
|
296
|
+
BASE + (uuid ? "zones/#{CGI.escape(uuid)}" : 'zones')
|
297
|
+
end
|
298
|
+
private_class_method :url
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Namespace for classes which access LiveDNS details.
|
4
|
+
class GandiV5
|
5
|
+
# Gandi LiveDNS Management API.
|
6
|
+
class LiveDNS
|
7
|
+
BASE = 'https://dns.api.gandi.net/api/v5/'
|
8
|
+
|
9
|
+
RECORD_TYPES = %w[
|
10
|
+
A AAAA CNAME MX NS TXT ALIAS
|
11
|
+
WKS SRV LOC SPF CAA DS SSHFP PTR KEY DNAME TLSA OPENPGPKEY CDS
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
# Raise an error if passed type is invalid.
|
15
|
+
# @param type [String] the record type to check.
|
16
|
+
# @return [nil]
|
17
|
+
# @raise [ArgumentError]
|
18
|
+
# rubocop:disable Style/GuardClause
|
19
|
+
def self.require_valid_record_type(type)
|
20
|
+
unless RECORD_TYPES.include?(type)
|
21
|
+
fail ArgumentError, "type must be one of #{RECORD_TYPES.join(', ')}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
# rubocop:enable Style/GuardClause
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
require_relative 'live_dns/record_set'
|
29
|
+
require_relative 'live_dns/domain'
|
30
|
+
require_relative 'live_dns/zone'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'email/mailbox'
|
4
|
+
require_relative 'email/offer'
|
5
|
+
require_relative 'email/slot'
|
6
|
+
|
7
|
+
class GandiV5
|
8
|
+
# The Organization API is a read-only API.
|
9
|
+
# All organization management must be performed via the web interface.
|
10
|
+
# @see https://api.gandi.net/docs/organization
|
11
|
+
# @!attribute [r] uuid
|
12
|
+
# @return [String] the sharing uuid of the user.
|
13
|
+
# @!attribute [r] username
|
14
|
+
# @return [String] the username of the user.
|
15
|
+
# @!attribute [r] name
|
16
|
+
# @return [String] the sharing name of the user.
|
17
|
+
# @!attribute [r] first_name
|
18
|
+
# @return [nil, String] the first name of the user.
|
19
|
+
# @!attribute [r] last_name
|
20
|
+
# @return [nil, String] the last name of the user.
|
21
|
+
# @!attribute [r] lang
|
22
|
+
# @return [String] language used by the user.
|
23
|
+
# @!attribute [r] street_address
|
24
|
+
# @return [nil, String] the street address of the user.
|
25
|
+
# @!attribute [r] city
|
26
|
+
# @return [String] the city name of the address.
|
27
|
+
# @!attribute [r] zip
|
28
|
+
# @return [nil, String] zip code of the address.
|
29
|
+
# @!attribute [r] country
|
30
|
+
# @return [nil, String] country ISO code of the address.
|
31
|
+
# @!attribute [r] email
|
32
|
+
# @return [String] the email address of the user.
|
33
|
+
# @!attribute [r] phone
|
34
|
+
# @return [nil, String] the phone number of the user.
|
35
|
+
# @!attribute [r] security_email
|
36
|
+
# @return [String] email address used for security processes such as account recovery.
|
37
|
+
# @!attribute [r] security_phone
|
38
|
+
# @return [nil, String]
|
39
|
+
# phone number used for security recovery processes such as totp recovery.
|
40
|
+
# @!attribute [r] security_email_validated
|
41
|
+
# @return [Boolean] state of the email validation process.
|
42
|
+
# @!attribute [r] security_email_validation_deadline
|
43
|
+
# @return [Time] deadline for the email address validation process.
|
44
|
+
class Organization
|
45
|
+
include GandiV5::Data
|
46
|
+
|
47
|
+
members :username, :name, :lang, :city, :zip, :country, :email, :phone, :security_phone,
|
48
|
+
:security_email, :security_email_validated, :security_email_validation_deadline
|
49
|
+
member :uuid, gandi_key: 'id'
|
50
|
+
member :first_name, gandi_key: 'firstname'
|
51
|
+
member :last_name, gandi_key: 'lastname'
|
52
|
+
member :street_address, gandi_key: 'streetaddr'
|
53
|
+
member :security_email_validation_deadline, converter: GandiV5::Data::Converter::Time
|
54
|
+
|
55
|
+
alias organization_uuid uuid
|
56
|
+
|
57
|
+
# Get information about the current authenticated user.
|
58
|
+
# @see https://api.gandi.net/docs/organization#get-v5-organization-user-info
|
59
|
+
# @return [GandiV5::Organization]
|
60
|
+
# @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
|
61
|
+
def self.fetch
|
62
|
+
data = GandiV5.get "#{BASE}organization/user-info"
|
63
|
+
from_gandi data
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|