gandi_v5 0.2.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +13 -3
  4. data/.travis.yml +15 -1
  5. data/CHANGELOG.md +63 -0
  6. data/FUNDING.yml +10 -0
  7. data/LICENSE.md +2 -6
  8. data/README.md +16 -21
  9. data/gandi_v5.gemspec +3 -2
  10. data/lib/gandi_v5.rb +64 -24
  11. data/lib/gandi_v5/billing.rb +0 -2
  12. data/lib/gandi_v5/billing/info.rb +0 -2
  13. data/lib/gandi_v5/data.rb +1 -4
  14. data/lib/gandi_v5/data/converter.rb +0 -4
  15. data/lib/gandi_v5/data/converter/integer.rb +26 -0
  16. data/lib/gandi_v5/domain.rb +167 -28
  17. data/lib/gandi_v5/domain/availability.rb +0 -3
  18. data/lib/gandi_v5/domain/availability/product.rb +0 -3
  19. data/lib/gandi_v5/domain/live_dns.rb +42 -0
  20. data/lib/gandi_v5/domain/renewal_information.rb +0 -3
  21. data/lib/gandi_v5/domain/sharing_space.rb +10 -2
  22. data/lib/gandi_v5/email.rb +0 -4
  23. data/lib/gandi_v5/email/forward.rb +102 -0
  24. data/lib/gandi_v5/email/mailbox.rb +57 -13
  25. data/lib/gandi_v5/email/slot.rb +11 -3
  26. data/lib/gandi_v5/error.rb +0 -2
  27. data/lib/gandi_v5/live_dns.rb +0 -16
  28. data/lib/gandi_v5/live_dns/domain.rb +221 -80
  29. data/lib/gandi_v5/live_dns/domain/dnssec_key.rb +115 -0
  30. data/lib/gandi_v5/live_dns/domain/record.rb +81 -0
  31. data/lib/gandi_v5/live_dns/domain/snapshot.rb +107 -0
  32. data/lib/gandi_v5/live_dns/domain/tsig_key.rb +71 -0
  33. data/lib/gandi_v5/organization.rb +38 -5
  34. data/lib/gandi_v5/organization/customer.rb +90 -0
  35. data/lib/gandi_v5/version.rb +1 -1
  36. data/spec/.rubocop.yml +9 -2
  37. data/spec/fixtures/bodies/GandiV5_Billing/{info.yaml → info.yml} +0 -0
  38. data/spec/fixtures/bodies/GandiV5_Domain/{get.yaml → fetch.yml} +8 -0
  39. data/spec/fixtures/bodies/GandiV5_Domain/{fetch_contacts.yaml → fetch_contacts.yml} +0 -0
  40. data/spec/fixtures/bodies/GandiV5_Domain/fetch_glue_records.yml +7 -0
  41. data/spec/fixtures/bodies/GandiV5_Domain/fetch_livedns.yml +6 -0
  42. data/spec/fixtures/bodies/GandiV5_Domain/fetch_name_servers.yml +2 -0
  43. data/spec/fixtures/bodies/GandiV5_Domain/{renewal_info.yaml → fetch_renewal_info.yml} +0 -3
  44. data/spec/fixtures/bodies/GandiV5_Domain/{restore_info.yaml → fetch_restore_info.yml} +0 -0
  45. data/spec/fixtures/bodies/GandiV5_Domain/{list.yaml → list.yml} +1 -0
  46. data/spec/fixtures/bodies/GandiV5_Domain_Availability/{fetch.yaml → fetch.yml} +0 -0
  47. data/spec/fixtures/bodies/GandiV5_Domain_TLD/{fetch.yaml → fetch.yml} +0 -0
  48. data/spec/fixtures/bodies/GandiV5_Domain_TLD/{list.yaml → list.yml} +0 -0
  49. data/spec/fixtures/bodies/GandiV5_Email_Forward/list.yml +6 -0
  50. data/spec/fixtures/bodies/GandiV5_Email_Mailbox/{get.yaml → fetch.yml} +0 -0
  51. data/spec/fixtures/bodies/GandiV5_Email_Mailbox/{list.yaml → list.yml} +0 -0
  52. data/spec/fixtures/bodies/GandiV5_Email_Slot/{get.yaml → fetch.yml} +0 -0
  53. data/spec/fixtures/bodies/GandiV5_Email_Slot/{list.yaml → list.yml} +0 -0
  54. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/fetch.yml +3 -0
  55. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/{list.yaml → list.yml} +0 -0
  56. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/list_tsig.yml +3 -0
  57. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/nameservers.yml +3 -0
  58. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_DnssecKey/fetch.yml +12 -0
  59. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_DnssecKey/list.yml +9 -0
  60. data/spec/fixtures/bodies/{GandiV5_LiveDNS_Zone_Snapshot/fetch.yaml → GandiV5_LiveDNS_Domain_Snapshot/fetch.yml} +4 -3
  61. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_Snapshot/list.yml +5 -0
  62. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_TsigKey/fetch.yml +9 -0
  63. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_TsigKey/list.yml +4 -0
  64. data/spec/fixtures/bodies/GandiV5_Organization/{get.yaml → fetch.yml} +0 -0
  65. data/spec/fixtures/bodies/GandiV5_Organization/list.yml +7 -0
  66. data/spec/fixtures/bodies/GandiV5_Organization_Customer/list.yml +8 -0
  67. data/spec/spec_helper.rb +2 -2
  68. data/spec/units/gandi_v5/billing_spec.rb +2 -2
  69. data/spec/units/gandi_v5/data/converter/integer_spec.rb +16 -0
  70. data/spec/units/gandi_v5/domain/availability_spec.rb +1 -1
  71. data/spec/units/gandi_v5/domain/live_dns_spec.rb +45 -0
  72. data/spec/units/gandi_v5/domain/tld_spec.rb +2 -2
  73. data/spec/units/gandi_v5/domain_spec.rb +294 -65
  74. data/spec/units/gandi_v5/email/forward_spec.rb +92 -0
  75. data/spec/units/gandi_v5/email/mailbox_spec.rb +122 -40
  76. data/spec/units/gandi_v5/email/slot_spec.rb +13 -5
  77. data/spec/units/gandi_v5/live_dns/domain/dnssec_key_spec.rb +128 -0
  78. data/spec/units/gandi_v5/live_dns/{record_set_spec.rb → domain/record_spec.rb} +1 -1
  79. data/spec/units/gandi_v5/live_dns/domain/snapshot_spec.rb +101 -0
  80. data/spec/units/gandi_v5/live_dns/domain/tsig_key_spec.rb +78 -0
  81. data/spec/units/gandi_v5/live_dns/domain_spec.rb +299 -120
  82. data/spec/units/gandi_v5/live_dns_spec.rb +0 -12
  83. data/spec/units/gandi_v5/organization/customer_spec.rb +81 -0
  84. data/spec/units/gandi_v5/organization_spec.rb +52 -1
  85. data/spec/units/gandi_v5_spec.rb +139 -30
  86. metadata +68 -95
  87. data/doc/GandiV5.html +0 -1183
  88. data/doc/GandiV5/Billing.html +0 -293
  89. data/doc/GandiV5/Billing/Info.html +0 -641
  90. data/doc/GandiV5/Billing/Info/Prepaid.html +0 -817
  91. data/doc/GandiV5/Data.html +0 -785
  92. data/doc/GandiV5/Data/ClassMethods.html +0 -223
  93. data/doc/GandiV5/Data/Converter.html +0 -433
  94. data/doc/GandiV5/Data/Converter/ArrayOf.html +0 -413
  95. data/doc/GandiV5/Data/Converter/Symbol.html +0 -322
  96. data/doc/GandiV5/Data/Converter/Time.html +0 -330
  97. data/doc/GandiV5/Domain.html +0 -16847
  98. data/doc/GandiV5/Domain/AutoRenew.html +0 -1237
  99. data/doc/GandiV5/Domain/Availability.html +0 -1020
  100. data/doc/GandiV5/Domain/Availability/Product.html +0 -988
  101. data/doc/GandiV5/Domain/Availability/Product/Period.html +0 -220
  102. data/doc/GandiV5/Domain/Availability/Product/Price.html +0 -1031
  103. data/doc/GandiV5/Domain/Availability/Tax.html +0 -440
  104. data/doc/GandiV5/Domain/Contact.html +0 -4459
  105. data/doc/GandiV5/Domain/Contract.html +0 -520
  106. data/doc/GandiV5/Domain/Dates.html +0 -1313
  107. data/doc/GandiV5/Domain/RenewalInformation.html +0 -1147
  108. data/doc/GandiV5/Domain/RestoreInformation.html +0 -339
  109. data/doc/GandiV5/Domain/SharingSpace.html +0 -437
  110. data/doc/GandiV5/Domain/TLD.html +0 -1565
  111. data/doc/GandiV5/Email.html +0 -144
  112. data/doc/GandiV5/Email/Mailbox.html +0 -6307
  113. data/doc/GandiV5/Email/Mailbox/Responder.html +0 -1560
  114. data/doc/GandiV5/Email/Offer.html +0 -514
  115. data/doc/GandiV5/Email/Slot.html +0 -4244
  116. data/doc/GandiV5/Error.html +0 -151
  117. data/doc/GandiV5/Error/GandiError.html +0 -270
  118. data/doc/GandiV5/LiveDNS.html +0 -300
  119. data/doc/GandiV5/LiveDNS/Domain.html +0 -2984
  120. data/doc/GandiV5/LiveDNS/RecordSet.html +0 -1593
  121. data/doc/GandiV5/LiveDNS/Zone.html +0 -8891
  122. data/doc/GandiV5/LiveDNS/Zone/Snapshot.html +0 -1556
  123. data/doc/GandiV5/Organization.html +0 -2341
  124. data/doc/_index.html +0 -474
  125. data/doc/class_list.html +0 -51
  126. data/doc/css/common.css +0 -1
  127. data/doc/css/full_list.css +0 -58
  128. data/doc/css/style.css +0 -496
  129. data/doc/file.README.html +0 -175
  130. data/doc/file_list.html +0 -56
  131. data/doc/frames.html +0 -17
  132. data/doc/index.html +0 -175
  133. data/doc/js/app.js +0 -303
  134. data/doc/js/full_list.js +0 -216
  135. data/doc/js/jquery.js +0 -4
  136. data/doc/method_list.html +0 -2427
  137. data/doc/top-level-namespace.html +0 -110
  138. data/lib/gandi_v5/live_dns/record_set.rb +0 -79
  139. data/lib/gandi_v5/live_dns/zone.rb +0 -305
  140. data/lib/gandi_v5/live_dns/zone/snapshot.rb +0 -81
  141. data/spec/features/domain_spec.rb +0 -45
  142. data/spec/features/livedns_domain_spec.rb +0 -8
  143. data/spec/features/livedns_zone_spec.rb +0 -45
  144. data/spec/features/mailbox_spec.rb +0 -18
  145. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/get.yaml +0 -4
  146. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/get.yaml +0 -11
  147. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/list.yaml +0 -11
  148. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/list.yaml +0 -3
  149. data/spec/fixtures/vcr/Domain_features/List_domains.yml +0 -54
  150. data/spec/fixtures/vcr/Domain_features/Renew_domain.yml +0 -133
  151. data/spec/fixtures/vcr/LiveDNS_Domain_features/List_domains.yml +0 -32
  152. data/spec/fixtures/vcr/LiveDNS_Zone_features/List_zones.yml +0 -42
  153. data/spec/fixtures/vcr/LiveDNS_Zone_features/Make_and_save_snapshot.yml +0 -72
  154. data/spec/fixtures/vcr/LiveDNS_Zone_features/Save_zone_to_file.yml +0 -28
  155. data/spec/fixtures/vcr/Mailbox_features/List_mailboxes.yml +0 -39
  156. data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +0 -66
  157. data/spec/units/gandi_v5/live_dns/zone_spec.rb +0 -347
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class LiveDNS
5
+ class Domain
6
+ # A DNSSEC key for a domain's DNS records.
7
+ # @!attribyte [r] uuid
8
+ # @return [String]
9
+ # @!attribyte [r] status
10
+ # @return [String]
11
+ # @!attribyte [r] fqdn
12
+ # @return [String]
13
+ # @!attribyte [r] algorithm_id
14
+ # @return [Integer]
15
+ # @!attribyte [r] algorithm_name
16
+ # @return [String]
17
+ # @!attribyte [r] deleted
18
+ # @return [Boolean]
19
+ # @!attribyte [r] ds
20
+ # @return [String]
21
+ # @!attribyte [r] flags
22
+ # @return [Integer]
23
+ # @!attribyte [r] fingerprint
24
+ # @return [String]
25
+ # @!attribyte [r] public_key
26
+ # @return [String]
27
+ # @!attribyte [r] tag
28
+ # @return [String]
29
+ class DnssecKey
30
+ include GandiV5::Data
31
+
32
+ members :status, :fqdn, :deleted, :ds, :flags, :fingerprint, :public_key,
33
+ :tag, :algorithm_name
34
+
35
+ member :uuid, gandi_key: 'id'
36
+ member :algorithm_id, gandi_key: 'algorithm'
37
+
38
+ # Delete this key.
39
+ # @return [String] The confirmation message from Gandi.
40
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
41
+ def delete
42
+ _response, data = GandiV5.delete url
43
+ self.deleted = true
44
+ data['message']
45
+ end
46
+
47
+ # Undelete this key.
48
+ # @return [String] The confirmation message from Gandi.
49
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
50
+ def undelete
51
+ _response, data = GandiV5.patch url, { deleted: false }.to_json
52
+ self.deleted = false
53
+ data['message']
54
+ end
55
+
56
+ # Check if this is a zone signing key
57
+ # @return [Boolean]
58
+ def zone_signing_key?
59
+ flags == 256
60
+ end
61
+
62
+ # Check if this is a key signing key
63
+ # @return [Boolean]
64
+ def key_signing_key?
65
+ flags == 257
66
+ end
67
+
68
+ # Create a new DNSSEC key for a zone.
69
+ # @param fqdn [String, #to_s] the fully qualified domain to create the key for.
70
+ # @param flags [Integer, :key_signing_key, :zone_signing_key] the key's flags.
71
+ # @return [GandiV5::LiveDNS::Domain::DnssecKey]
72
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
73
+ def self.create(fqdn, flags)
74
+ flags = 256 if flags == :zone_signing_key
75
+ flags = 257 if flags == :key_signing_key
76
+ fail ArgumentError, 'flags is invalid' unless flags.is_a?(Integer)
77
+
78
+ response, _data = GandiV5.post url(fqdn), { flags: flags }.to_json
79
+ fetch fqdn, response.headers[:location].split('/').last
80
+ end
81
+
82
+ # Get keys for a FQDN from Gandi.
83
+ # @param fqdn [String, #to_s] The fully qualified domain name to get the keys for.
84
+ # @return [Array<GandiV5::LiveDNS::Domain::DnssecKey>]
85
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
86
+ def self.list(fqdn)
87
+ _response, data = GandiV5.get url(fqdn)
88
+ data.map { |item| from_gandi item }
89
+ end
90
+
91
+ # Get DNSSEC key from Gandi.
92
+ # @param fqdn [String, #to_s] The fully qualified domain name the key was made for.
93
+ # @param uuid [String, #to_s] the UUID of the key to fetch.
94
+ # @return [GandiV5::LiveDNS::Domain::DnssecKey]
95
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
96
+ def self.fetch(fqdn, uuid)
97
+ _response, data = GandiV5.get url(fqdn, uuid)
98
+ from_gandi data
99
+ end
100
+
101
+ private
102
+
103
+ def url
104
+ "#{BASE}livedns/domains/#{CGI.escape fqdn}/keys/#{CGI.escape uuid}"
105
+ end
106
+
107
+ def self.url(fqdn, uuid = nil)
108
+ "#{BASE}livedns/domains/#{CGI.escape fqdn}/keys" +
109
+ (uuid ? "/#{CGI.escape uuid}" : '')
110
+ end
111
+ private_class_method :url
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class LiveDNS
5
+ class Domain
6
+ # A record set which comes from either a domain or zone.
7
+ # @!attribute [r] type
8
+ # @return [String]
9
+ # @!attribute [r] ttl
10
+ # @return [Integer]
11
+ # @!attribute [r] name
12
+ # @return [String]
13
+ # @!attribute [r] values
14
+ # @return [Array<String>]
15
+ class Record
16
+ include GandiV5::Data
17
+
18
+ member :type, gandi_key: 'rrset_type'
19
+ member :ttl, gandi_key: 'rrset_ttl', converter: GandiV5::Data::Converter::Integer
20
+ member :name, gandi_key: 'rrset_name'
21
+ member :values, gandi_key: 'rrset_values'
22
+
23
+ # Generate zone file lines for the record.
24
+ # @return [String]
25
+ def to_s
26
+ values.map do |value|
27
+ "#{name}\t#{ttl}\tIN\t#{type}\t#{value}"
28
+ end.join("\n")
29
+ end
30
+
31
+ GandiV5::LiveDNS::RECORD_TYPES.each do |t|
32
+ # Check the record type.
33
+ # @return [Boolean]
34
+ define_method "#{t.downcase}?" do
35
+ type.eql?(t)
36
+ end
37
+ end
38
+
39
+ # Check the TTL's value in seconds.
40
+ # @param number [Integer] the number of second(s) to check against.
41
+ # @return [Boolean]
42
+ def second?(number = 1)
43
+ ttl == number
44
+ end
45
+ alias seconds? second?
46
+
47
+ # Check the TTL's value in minutes.
48
+ # @param number [Integer] the number of minute(s) to check against.
49
+ # @return [Boolean]
50
+ def minute?(number = 1)
51
+ ttl == number * 60
52
+ end
53
+ alias minutes? minute?
54
+
55
+ # Check the TTL's value in hours.
56
+ # @param number [Integer] the number of hour(s) to check against.
57
+ # @return [Boolean]
58
+ def hour?(number = 1)
59
+ ttl == number * 3_600
60
+ end
61
+ alias hours? hour?
62
+
63
+ # Check the TTL's value in days.
64
+ # @param number [Integer] the number of day(s) to check against.
65
+ # @return [Boolean]
66
+ def day?(number = 1)
67
+ ttl == number * 86_400
68
+ end
69
+ alias days? day?
70
+
71
+ # Check the TTL's value in weeks.
72
+ # @param number [Integer] the number of week(s) to check against.
73
+ # @return [Boolean]
74
+ def week?(number = 1)
75
+ ttl == number * 604_800
76
+ end
77
+ alias weeks? day?
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class LiveDNS
5
+ class Domain
6
+ # A snapshot (backup) of a domain's DNS records.
7
+ # @!attribute [r] fqdn
8
+ # @return [String]
9
+ # @!attribute [r] uuid
10
+ # @return [String]
11
+ # @!attribute [r] name
12
+ # @return [String]
13
+ # @!attribute [r] created_at
14
+ # @return [Time]
15
+ # @!attribute [r] automatic
16
+ # @return [Boolean]
17
+ class Snapshot
18
+ include GandiV5::Data
19
+
20
+ members :name, :automatic, :fqdn
21
+ member :created_at, converter: GandiV5::Data::Converter::Time
22
+ member :uuid, gandi_key: 'id'
23
+ member(
24
+ :records,
25
+ gandi_key: 'zone_data',
26
+ converter: GandiV5::LiveDNS::Domain::Record,
27
+ array: true
28
+ )
29
+
30
+ alias snapshot_uuid uuid
31
+
32
+ # Delete this snapshot.
33
+ # @return [String] The confirmation message from Gandi.
34
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
35
+ def delete
36
+ _response, data = GandiV5.delete url
37
+ data['message']
38
+ end
39
+
40
+ # Update this snapshot.
41
+ # @param name [String, #to_s] new name for the snapshot.
42
+ # @return [String] The confirmation message from Gandi.
43
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
44
+ def update(name:)
45
+ _response, data = GandiV5.patch url, { name: name }.to_json
46
+ self.name = name
47
+ data['message']
48
+ end
49
+
50
+ # Get snapshot details for this FQDN from Gandi.
51
+ # @param fqdn [String, #to_s] The fully qualified domain name to get the snapshots for.
52
+ # @param page [#each<Integer, #to_s>] the page(s) of results to retrieve.
53
+ # If page is not provided keep querying until an empty list is returned.
54
+ # If page responds to .each then iterate until an empty list is returned.
55
+ # @param per_page [Integer, #to_s] (optional default 100) how many results to get per page.
56
+ # @param automatic [nil, Boolean] (optional) filter by automatic or manual snapshot.
57
+ # @return [Array<GandiV5::LiveDNS::Domain::Snapshot>]
58
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
59
+ def self.list(fqdn, page: (1..), per_page: 100, **params)
60
+ params.reject! { |_k, v| v.nil? }
61
+
62
+ snapshots = []
63
+ GandiV5.paginated_get(url(fqdn), page, per_page, params: params) do |data|
64
+ snapshots += data.map { |item| from_gandi item.merge(fqdn: fqdn) }
65
+ end
66
+ snapshots
67
+ end
68
+
69
+ # Get snapshot from Gandi.
70
+ # @param fqdn [String, #to_s] The fully qualified domain name the snapshot was made for.
71
+ # @param uuid [String, #to_s] the UUID of the snapshot to fetch.
72
+ # @return [GandiV5::LiveDNS::Domain::Snapshot]
73
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
74
+ def self.fetch(fqdn, uuid)
75
+ _response, data = GandiV5.get url(fqdn, uuid)
76
+ from_gandi data.merge(fqdn: fqdn)
77
+ end
78
+
79
+ # Get the records which makeup this snapshot (fetching from Gandi if required).
80
+ # @return [Array<GandiV5::LiveDNS::Domain::Record>]
81
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
82
+ def records
83
+ return @records unless @records.nil?
84
+
85
+ @records = fetch_records
86
+ end
87
+
88
+ private
89
+
90
+ def fetch_records
91
+ _response, data = GandiV5.get url
92
+ data.fetch('zone_data').map { |item| GandiV5::LiveDNS::Domain::Record.from_gandi item }
93
+ end
94
+
95
+ def url
96
+ "#{BASE}livedns/domains/#{CGI.escape fqdn}/snapshots/#{CGI.escape uuid}"
97
+ end
98
+
99
+ def self.url(fqdn, snapshot_uuid = nil)
100
+ "#{BASE}livedns/domains/#{CGI.escape fqdn}/snapshots" +
101
+ (snapshot_uuid ? "/#{CGI.escape snapshot_uuid}" : '')
102
+ end
103
+ private_class_method :url
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class LiveDNS
5
+ class Domain
6
+ # A Tsig key.
7
+ # @!attribyte [r] uuid
8
+ # @return [String]
9
+ # @!attribyte [r] name
10
+ # @return [String]
11
+ # @!attribyte [r] secret
12
+ # @return [String]
13
+ # @!attribyte [r] config_examples
14
+ # @return [Hash<Symbol -> String>]
15
+ class TsigKey
16
+ include GandiV5::Data
17
+
18
+ member :secret
19
+ member :uuid, gandi_key: 'id'
20
+ member :name, gandi_key: 'key_name'
21
+ member(
22
+ :config_examples,
23
+ gandi_key: 'config_samples',
24
+ converter: GandiV5::Data::Converter.new(
25
+ from_gandi: ->(value) { value.transform_keys(&:to_sym) },
26
+ to_gandi: ->(_value) { nil }
27
+ )
28
+ )
29
+
30
+ # Create a new DNSSEC key for a zone.
31
+ # @param sharing_id [nil, String, #to_s]
32
+ # @return [GandiV5::LiveDNS::Domain::DnssecKey]
33
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
34
+ def self.create(sharing_id = nil)
35
+ url_ = url
36
+ url_ += "?sharing_id=#{CGI.escape sharing_id}" if sharing_id
37
+
38
+ _response, data = GandiV5.post url_
39
+ fetch data.fetch('id')
40
+ end
41
+
42
+ # Get keys from Gandi.
43
+ # If you need the secret, fingerprint, public_key or tag attributes you'll need
44
+ # to use GandiV5::LiveDNS::Domain::DnssecKey.fetch on each item.
45
+ # @return [Array<GandiV5::LiveDNS::Domain::TsigKey>]
46
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
47
+ def self.list
48
+ _response, data = GandiV5.get url
49
+ data.map { |item| from_gandi item }
50
+ end
51
+
52
+ # Get Tsig key from Gandi.
53
+ # @param uuid [String, #to_s] the UUID of the key to fetch.
54
+ # @return [GandiV5::LiveDNS::Domain::TsigKey]
55
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
56
+ def self.fetch(uuid)
57
+ _response, data = GandiV5.get url(uuid)
58
+ from_gandi data
59
+ end
60
+
61
+ private
62
+
63
+ def self.url(uuid = nil)
64
+ "#{BASE}livedns/axfr/tsig" +
65
+ (uuid ? "/#{CGI.escape uuid}" : '')
66
+ end
67
+ private_class_method :url
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'email/mailbox'
4
- require_relative 'email/offer'
5
- require_relative 'email/slot'
6
-
7
3
  class GandiV5
8
4
  # The Organization API is a read-only API.
9
5
  # All organization management must be performed via the web interface.
@@ -54,13 +50,50 @@ class GandiV5
54
50
 
55
51
  alias organization_uuid uuid
56
52
 
53
+ # @see GandiV5::Organization::Customer.list
54
+ def customers(org_uuid, **params)
55
+ GandiV5::Organization::Customer.list(org_uuid, **params)
56
+ end
57
+
58
+ # @see GandiV5::Organization::Customer.create
59
+ def create_customer(org_uuid, **params)
60
+ GandiV5::Organization::Customer.create(org_uuid, **params)
61
+ end
62
+
57
63
  # Get information about the current authenticated user.
58
64
  # @see https://api.gandi.net/docs/organization#get-v5-organization-user-info
59
65
  # @return [GandiV5::Organization]
60
66
  # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
61
67
  def self.fetch
62
- _response, data = GandiV5.get "#{BASE}organization/user-info"
68
+ _response, data = GandiV5.get "#{url}/user-info"
63
69
  from_gandi data
64
70
  end
71
+
72
+ # List organisations.
73
+ # @see https://api.gandi.net/docs/domains#get-v5-organization-organizations
74
+ # @param name [String, #to_s] (optional)
75
+ # filters the list by name, with optional patterns.
76
+ # e.g. "alice", "ali*", "*ice"
77
+ # @param type [String, #to_s] (optional)
78
+ # filters the list by type of organization.
79
+ # One of: "individual", "company", "association", "publicbody"
80
+ # @param permission [String, #to_s] (optional)
81
+ # filters the list by the permission the authenticated user
82
+ # has on that organization and products in it.
83
+ # @param sort_by [String, #to_s] (optional default "name") how to sort the list.
84
+ # @return [Array<GandiV5::Organization>]
85
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
86
+ def self.list(**params)
87
+ params['~name'] = params.delete(:name) if params.key?(:name)
88
+ _resp, data = GandiV5.get "#{url}/organizations", params: params
89
+ data.map { |organisation| from_gandi organisation }
90
+ end
91
+
92
+ private
93
+
94
+ def self.url
95
+ "#{BASE}organization"
96
+ end
97
+ private_class_method :url
65
98
  end
66
99
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class Organization
5
+ # A customer of a reseller organization
6
+ # @!attribute [r] id
7
+ # @return [String] The main identifier of the customer.
8
+ # Also known as sharing_id in many routes.
9
+ # @!attribute [r] email
10
+ # @return [String] Email of the customer.
11
+ # @!attribute [r] first_name
12
+ # @return [String] First name of the customer.
13
+ # @!attribute [r] last_name
14
+ # @return [String] Last name of the customer.
15
+ # @!attribute [r] name
16
+ # @return [String] Name of the customer.
17
+ # @!attribute [r] type
18
+ # @return [:individual, :company, :association, :publicbody]
19
+ # @!attribute [r] org_name
20
+ # @return [nil, String] Organization legal name of the customer..
21
+ class Customer
22
+ include GandiV5::Data
23
+
24
+ members :email, :name
25
+ member :uuid, gandi_key: 'id'
26
+ member :first_name, gandi_key: 'firstname'
27
+ member :last_name, gandi_key: 'lastname'
28
+ member :org_name, gandi_key: 'orgname'
29
+ member :type, converter: GandiV5::Data::Converter::Symbol
30
+
31
+ # Create a new customer for this organization.
32
+ # @see https://api.gandi.net/docs/organization/#post-v5-organization-organizations-id-customers
33
+ # @param org_uuid [String] UUID of the organization to create the customer for.
34
+ # @param firstname [String, #to_s] (required) Customer's first name.
35
+ # @param lastname [String, #to_s] (required) Customer's last name.
36
+ # @param type [String, #to_s] (required) Type of customer
37
+ # ("individual", "company", "association" or "publicbody").
38
+ # @param streetaddr [String, #to_s] (required) Customer's street address.
39
+ # @param city [String, #to_s] (required) Customer's city.
40
+ # @param country [String, #to_s] (required) Customer's country.
41
+ # @param email [String, #to_s] (required) Customer's email address.
42
+ # @param phone [String, #to_s] (required) Customer's phone number.
43
+ # @param fax [String, #to_s] (optional) Customer's fax number.
44
+ # @param streetaddr2 [String, #to_s] (optional) Customer's street address (2nd line).
45
+ # @param state [String, #to_s] (optional) Customer's state/province/region.
46
+ # @param zip [String, #to_s] (optional) Customer's postal/zip code.
47
+ # @param reference [String, #to_s] (optional)
48
+ # Optional text to display on the invoice, such as your own customer reference info.
49
+ # @param orgname [String, #to_s] (optional) Customer Organization's legal name.
50
+ # @return [nil]
51
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error
52
+ def self.create(org_uuid, **params)
53
+ %i[city country email firstname lastname phone streetaddr type].each do |attr|
54
+ fail ArgumentError, "missing keyword: #{attr}" unless params.key?(attr)
55
+ end
56
+ unless %w[individual company association publicbody].include?(params[:type].to_s)
57
+ fail ArgumentError, "invalid type: #{params[:type].inspect}"
58
+ end
59
+
60
+ _response, _data = GandiV5.post(url(org_uuid), params.to_json)
61
+ nil
62
+ end
63
+
64
+ # List organisation's customers.
65
+ # @see https://api.gandi.net/docs/organization/#get-v5-organization-organizations-id-customers
66
+ # @param org_uuid [String] UUID of the organization to fetch customers for.
67
+ # @param name [String, #to_s] (optional)
68
+ # filters the list by name, with optional patterns.
69
+ # e.g. "alice", "ali*", "*ice"
70
+ # @param permission [String, #to_s] (optional)
71
+ # filters the list by the permission the authenticated user has on
72
+ # that organization and products in it.
73
+ # @param sort_by [String, #to_s] (optional default "name") how to sort the list.
74
+ # @return [Array<GandiV5::Organization>]
75
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
76
+ def self.list(org_uuid, **params)
77
+ params['~name'] = params.delete(:name) if params.key?(:name)
78
+ _resp, data = GandiV5.get url(org_uuid), params: params
79
+ data.map { |organisation| from_gandi organisation }
80
+ end
81
+
82
+ private
83
+
84
+ def self.url(org_uuid)
85
+ "#{BASE}organization/organizations/#{org_uuid}/customers"
86
+ end
87
+ private_class_method :url
88
+ end
89
+ end
90
+ end