gandi_v5 0.6.0 → 0.10.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.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +81 -5
  3. data/README.md +65 -14
  4. data/lib/gandi_v5.rb +139 -70
  5. data/lib/gandi_v5/billing/info/prepaid.rb +1 -0
  6. data/lib/gandi_v5/data.rb +3 -2
  7. data/lib/gandi_v5/data/converter.rb +3 -2
  8. data/lib/gandi_v5/data/converter/array_of.rb +3 -2
  9. data/lib/gandi_v5/data/converter/integer.rb +3 -2
  10. data/lib/gandi_v5/data/converter/symbol.rb +3 -2
  11. data/lib/gandi_v5/data/converter/time.rb +3 -2
  12. data/lib/gandi_v5/domain.rb +55 -18
  13. data/lib/gandi_v5/domain/availability/product/period.rb +1 -1
  14. data/lib/gandi_v5/domain/contact.rb +5 -5
  15. data/lib/gandi_v5/domain/tld.rb +2 -2
  16. data/lib/gandi_v5/domain/transfer_in.rb +172 -0
  17. data/lib/gandi_v5/domain/transfer_in/availability.rb +51 -0
  18. data/lib/gandi_v5/domain/web_forwarding.rb +182 -0
  19. data/lib/gandi_v5/email.rb +3 -0
  20. data/lib/gandi_v5/email/forward.rb +3 -9
  21. data/lib/gandi_v5/email/mailbox.rb +5 -11
  22. data/lib/gandi_v5/error/gandi_error.rb +1 -0
  23. data/lib/gandi_v5/live_dns.rb +2 -12
  24. data/lib/gandi_v5/live_dns/domain.rb +340 -29
  25. data/lib/gandi_v5/live_dns/domain/dnssec_key.rb +120 -0
  26. data/lib/gandi_v5/live_dns/domain/record.rb +81 -0
  27. data/lib/gandi_v5/live_dns/domain/snapshot.rb +111 -0
  28. data/lib/gandi_v5/live_dns/domain/tsig_key.rb +74 -0
  29. data/lib/gandi_v5/sharing_space.rb +27 -0
  30. data/lib/gandi_v5/simple_hosting.rb +13 -0
  31. data/lib/gandi_v5/simple_hosting/instance.rb +251 -0
  32. data/lib/gandi_v5/simple_hosting/instance/application.rb +45 -0
  33. data/lib/gandi_v5/simple_hosting/instance/database.rb +20 -0
  34. data/lib/gandi_v5/simple_hosting/instance/language.rb +22 -0
  35. data/lib/gandi_v5/simple_hosting/instance/upgrade.rb +22 -0
  36. data/lib/gandi_v5/simple_hosting/instance/virtual_host.rb +272 -0
  37. data/lib/gandi_v5/simple_hosting/instance/virtual_host/linked_dns_zone.rb +75 -0
  38. data/lib/gandi_v5/template.rb +271 -0
  39. data/lib/gandi_v5/template/dispatch.rb +109 -0
  40. data/lib/gandi_v5/template/payload.rb +64 -0
  41. data/lib/gandi_v5/template/payload/dns_record.rb +23 -0
  42. data/lib/gandi_v5/template/payload/web_forwarding.rb +82 -0
  43. data/lib/gandi_v5/version.rb +1 -1
  44. data/spec/.rubocop.yml +9 -9
  45. data/spec/features/list_domain_renewals_spec.rb +16 -0
  46. data/spec/features/list_email_addresses_spec.rb +39 -0
  47. data/spec/fixtures/bodies/GandiV5_Domain_TransferIn/fetch.yml +21 -0
  48. data/spec/fixtures/bodies/GandiV5_Domain_TransferIn_Availability/fetch.yml +10 -0
  49. data/spec/fixtures/bodies/GandiV5_Domain_WebForwarding/fetch.yml +9 -0
  50. data/spec/fixtures/bodies/GandiV5_Domain_WebForwarding/list.yml +9 -0
  51. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/fetch.yml +1 -2
  52. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/list_tsig.yml +3 -0
  53. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/nameservers.yml +3 -0
  54. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_DnssecKey/fetch.yml +12 -0
  55. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_DnssecKey/list.yml +9 -0
  56. data/spec/fixtures/bodies/{GandiV5_LiveDNS_Zone_Snapshot → GandiV5_LiveDNS_Domain_Snapshot}/fetch.yml +4 -3
  57. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_Snapshot/list.yml +5 -0
  58. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_TsigKey/fetch.yml +9 -0
  59. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain_TsigKey/list.yml +4 -0
  60. data/spec/fixtures/bodies/GandiV5_SimpleHosting_Instance/fetch.yml +80 -0
  61. data/spec/fixtures/bodies/GandiV5_SimpleHosting_Instance/list.yml +38 -0
  62. data/spec/fixtures/bodies/GandiV5_SimpleHosting_Instance_VirtualHost/fetch.yml +26 -0
  63. data/spec/fixtures/bodies/GandiV5_SimpleHosting_Instance_VirtualHost/list.yml +18 -0
  64. data/spec/fixtures/bodies/GandiV5_Template/fetch.yml +41 -0
  65. data/spec/fixtures/bodies/GandiV5_Template/list.yml +20 -0
  66. data/spec/fixtures/bodies/GandiV5_Template_Dispatch/fetch.yml +49 -0
  67. data/spec/fixtures/vcr/Examples/List_domain_renewals.yml +54 -0
  68. data/spec/fixtures/vcr/Examples/List_email_addresses.yml +103 -0
  69. data/spec/spec_helper.rb +8 -7
  70. data/spec/units/gandi_v5/domain/transfer_in/availability_spec.rb +49 -0
  71. data/spec/units/gandi_v5/domain/transfer_in_spec.rb +143 -0
  72. data/spec/units/gandi_v5/domain/web_forwarding_spec.rb +150 -0
  73. data/spec/units/gandi_v5/domain_spec.rb +56 -37
  74. data/spec/units/gandi_v5/email/forward_spec.rb +5 -34
  75. data/spec/units/gandi_v5/email/mailbox_spec.rb +4 -34
  76. data/spec/units/gandi_v5/live_dns/domain/dnssec_key_spec.rb +128 -0
  77. data/spec/units/gandi_v5/live_dns/{record_set_spec.rb → domain/record_spec.rb} +1 -1
  78. data/spec/units/gandi_v5/live_dns/domain/snapshot_spec.rb +101 -0
  79. data/spec/units/gandi_v5/live_dns/domain/tsig_key_spec.rb +78 -0
  80. data/spec/units/gandi_v5/live_dns/domain_spec.rb +297 -118
  81. data/spec/units/gandi_v5/live_dns_spec.rb +0 -12
  82. data/spec/units/gandi_v5/simple_hosting/instance/application_spec.rb +37 -0
  83. data/spec/units/gandi_v5/simple_hosting/instance/virtual_host/linked_dns_zone_spec.rb +50 -0
  84. data/spec/units/gandi_v5/simple_hosting/instance/virtual_host_spec.rb +324 -0
  85. data/spec/units/gandi_v5/simple_hosting/instance_spec.rb +190 -0
  86. data/spec/units/gandi_v5/simple_hosting_spec.rb +9 -0
  87. data/spec/units/gandi_v5/template/dispatch_spec.rb +70 -0
  88. data/spec/units/gandi_v5/template/payload/web_forwarding_spec.rb +44 -0
  89. data/spec/units/gandi_v5/template_spec.rb +341 -0
  90. data/spec/units/gandi_v5_spec.rb +111 -14
  91. metadata +226 -79
  92. data/.gitignore +0 -26
  93. data/.rspec +0 -3
  94. data/.rubocop.yml +0 -30
  95. data/.travis.yml +0 -38
  96. data/FUNDING.yml +0 -10
  97. data/Gemfile +0 -6
  98. data/Guardfile +0 -39
  99. data/Rakefile +0 -3
  100. data/bin/console +0 -13
  101. data/gandi_v5.gemspec +0 -42
  102. data/lib/gandi_v5/domain/sharing_space.rb +0 -29
  103. data/lib/gandi_v5/live_dns/has_zone_records.rb +0 -153
  104. data/lib/gandi_v5/live_dns/record_set.rb +0 -79
  105. data/lib/gandi_v5/live_dns/zone.rb +0 -160
  106. data/lib/gandi_v5/live_dns/zone/snapshot.rb +0 -81
  107. data/spec/features/domain_spec.rb +0 -45
  108. data/spec/features/livedns_domain_spec.rb +0 -8
  109. data/spec/features/livedns_zone_spec.rb +0 -44
  110. data/spec/features/mailbox_spec.rb +0 -18
  111. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/fetch.yml +0 -11
  112. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/list.yml +0 -11
  113. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/list.yml +0 -3
  114. data/spec/fixtures/vcr/Domain_features/List_domains.yml +0 -55
  115. data/spec/fixtures/vcr/Domain_features/Renew_domain.yml +0 -133
  116. data/spec/fixtures/vcr/LiveDNS_Domain_features/List_domains.yml +0 -32
  117. data/spec/fixtures/vcr/LiveDNS_Zone_features/List_zones.yml +0 -42
  118. data/spec/fixtures/vcr/LiveDNS_Zone_features/Make_and_save_snapshot.yml +0 -72
  119. data/spec/fixtures/vcr/LiveDNS_Zone_features/Save_zone_to_file.yml +0 -28
  120. data/spec/fixtures/vcr/Mailbox_features/List_mailboxes.yml +0 -39
  121. data/spec/units/gandi_v5/billing/info_spec.rb +0 -4
  122. data/spec/units/gandi_v5/domain/availability/product/period_spec.rb +0 -4
  123. data/spec/units/gandi_v5/domain/availability/product/price_spec.rb +0 -4
  124. data/spec/units/gandi_v5/domain/availability/product_spec.rb +0 -4
  125. data/spec/units/gandi_v5/domain/availability/tax_spec.rb +0 -4
  126. data/spec/units/gandi_v5/domain/contract_spec.rb +0 -4
  127. data/spec/units/gandi_v5/domain/dates_spec.rb +0 -4
  128. data/spec/units/gandi_v5/domain/restore_information_spec.rb +0 -4
  129. data/spec/units/gandi_v5/domain/sharing_space_spec.rb +0 -4
  130. data/spec/units/gandi_v5/error_spec.rb +0 -4
  131. data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +0 -66
  132. data/spec/units/gandi_v5/live_dns/zone_spec.rb +0 -347
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 023623b5d81a2f3acc4a5fee812f0e8ca24dd8735f59a0f12b53ad35ddb7a397
4
- data.tar.gz: 3cf89099c45295da9b06a53ad64b601b3a77525a13ddade403d600c382be02d3
3
+ metadata.gz: cc90c3434cb1207a7eed04d4b2331039f8ac8e32e2861e4d3693b034658eabb1
4
+ data.tar.gz: 51b125b39d4b4fe71a2fc4f55815bf8c4e5c94a5d7e01bfd9e104be1886a91fa
5
5
  SHA512:
6
- metadata.gz: 5e816b9de44330c832f6591ca6724b44f5b05c6fab53d8fda6d13a9820211292f29ee608953d8a562da97f4bcfee38f24f799b4a68184bba2b0ec751d21b3f61
7
- data.tar.gz: 622bded49d8bae3129ad74fae6fcaf1e8d7c3639b40348b7537e0ba46a3d5c668d2a134754dcf1ff31bcffe3cf0797f5c4368cbc849c386b4648f850d9e24117
6
+ metadata.gz: 6478500701daaeec1623ce28db9d0568a9971f6087d7d7064d13cded11afa76e24b987e7804b7a88a2b5f3b4aa0496b860352399be8fcd82cdb88b640ba1c5e8
7
+ data.tar.gz: bd3089b11811fc944acaf7d39798d45a36c5e17a9a5be90d2a90d07270a2ca835e73428f58d641893d79f074b96a7c42671efb1ed2c4c40ca838840a0ee87759
@@ -1,5 +1,81 @@
1
1
  # Gandi V5 API Gem Changelog
2
2
 
3
+ ## Version 0.10.0
4
+
5
+ * GandiV5::Domain
6
+ * Add \#transfer_lock(lock = true) and \#transfer_unlock
7
+ * Add template_id argument to .create
8
+ * Add \#web_forwardings -> GandiV5::Domain::WebForwarding.list
9
+ * Add \#new_web_forwarding -> GandiV5::Domain::WebForwarding.create
10
+ * GandiV5::Domain::TransferIn
11
+ * Add template_id argument to .create
12
+ * GandiV5::Domain::WebForwarding
13
+ * GandiV5::SimpleHosting::Instance::VirtualHost: (I don't use simple hosting myself so it's possible I've misread the docs and a bug is waiting to be found, please add an issue if I have)
14
+ * Add .create (aliased as GandiV5::SimpleHosting::Instance#create_virtual_host)
15
+ * Add \#delete
16
+ * Add \#update
17
+ * GandiV5::Template
18
+ * GandiV5::Template::Dispatch
19
+ * Add testing against truffleruby-20.3.0
20
+
21
+ ## Version 0.9.1
22
+
23
+ * Add testing against ruby 2.7.2 and 3.0.0
24
+
25
+ ## Version 0.9.0
26
+
27
+ * Add transferring a domain to Gandi (I don't have any domains outside Gandi to test this myself so it's possible I've misread the docs and a bug is waiting to be found, please add an issue if I have):
28
+ * GandiV5::Domain::TransferIn:
29
+ * .create(fqdn, \*\*options)
30
+ * .fetch(fqdn)
31
+ * .relaunch(fqdn)
32
+ * .resend_foa_emails(fqdn, email_address)
33
+ * \#relaunch
34
+ * \#resend_foa_emails(email_address)
35
+ * GandiV5::Domain::TransferIn::Availabillity:
36
+ * .fetch(fqdn, auth_code = nil)
37
+ * Documentation improvements
38
+
39
+ ## Version 0.8.0
40
+
41
+ * Domain:
42
+ * .list - add resellee_id filter
43
+ * Added simple hosting: (I don't use simple hosting myself so it's possible I've misread the docs and a bug is waiting to be found, please add an issue if I have)
44
+ * SimpleHosting::Instance
45
+ * SimpleHosting::Instance::VirtualHost
46
+ * SimpleHosting::Instance::Application
47
+ * SimpleHosting::Instance::Database
48
+ * SimpleHosting::Instance::Language
49
+ * SimpleHosting::Instance::Upgrade
50
+ * GandiV5::Domain::SharingSpace moved to GandiV5::SharingSpace
51
+
52
+ ## Version 0.7.0
53
+
54
+ * LiveDNS:
55
+ * Rename LiveDNS::RecordSet to LiveDNS::Domain::Record
56
+ * Domains:
57
+ * .list now returns an array of strings
58
+ * Can no longer change the zone used by a domain
59
+ * Added automatic_snapshots attribute for whether snapshots are automatically created when a modification is made to this domain's records
60
+ * \#replace_records and \#replace_records_for merged into \#replace_records
61
+ * If replacing with a zone file use the new #replace_zone_lines
62
+ * Added:
63
+ * .create
64
+ * .record_types
65
+ * .generic_name_servers(fqdn)
66
+ * \#name_servers and #fetch_name_servers
67
+ * \#tsig_keys, #fetch_tsig_keys, \#add_tsig_key, \#remove_tsig_key
68
+ * \#axfr_clients, #fetch_axfr_clients, #add_axfr_client, \#remove_axfr_client
69
+ * ::DnssecKeys, #dnssec_keys, #fetch_dnssec_keys
70
+ * Snapshots:
71
+ * Moved to live under LiveDNS::Domain not LiveDNS::Zone
72
+ * Are now accessed via the fully qualified domain name NOT the zone's UUID
73
+ * Ability to access the zone from a snapshot is removed
74
+ * Taking a snapshot now allows for named snapshots
75
+ * Added automatic attribute for when a snapshot was taken due to a zone change
76
+ * .list now returns an array of snapshots (records are fetched in a seperate request when first needed)
77
+ * Zone removed.
78
+
3
79
  ## Version 0.6.0
4
80
 
5
81
  * GandiV5::Email::Slot.create now supports sharing_id
@@ -39,11 +115,11 @@
39
115
  ## Version 0.2.0
40
116
 
41
117
  * Enhancements to GandiV5::Domain
42
- * .availability(fqdn, **options) moved to GandiV5::Domain::Availability.fetch(fqdn, **options)
118
+ * .availability(fqdn, \*\*options) moved to GandiV5::Domain::Availability.fetch(fqdn, \*\*options)
43
119
  * .create now returns created domain (except in dry-run mode)
44
120
  * .tlds moved to GandiV5::Domain::TLD.list
45
121
  * .tld(name) moved to GandiV5::Domain::TLD.fetch(name)
46
- * #renewal_price(currency: 'GBP', period: 1) added
122
+ * \#renewal_price(currency: 'GBP', period: 1) added
47
123
  * Enhancements to GandiV5::Email::Mailbox
48
124
  * .create now returns created mailbox
49
125
  * .create now checks for available slots and a valid type has been passed
@@ -52,14 +128,14 @@
52
128
  * Add #disable to disable the auto responder in Gandi
53
129
  * Enhancements to GandiV5::Email::Slot
54
130
  * .create now returns created slot
55
- * #delete now checks for inactiveness and refundableness
131
+ * \#delete now checks for inactiveness and refundableness
56
132
  * Enhancements to GandiV5::LiveDNS::Domain
57
133
  * Add #zone and #fetch_zone
58
- * Remove #replace_*_records_for methods
134
+ * Remove #replace_\*_records_for methods
59
135
  * Changes to #replace_records_for to allow calling with name, type, ttl and values. When calling with name and fecords records MUST be passed as an array.
60
136
  * Enhancements to GandiV5::LiveDNS::Zone
61
137
  * .create now returns created zone
62
- * Remove #replace_*_records_for methods
138
+ * Remove #replace_\*_records_for methods
63
139
  * Changes to #replace_records_for to allow calling with name, type, ttl and values. When calling with name and fecords records MUST be passed as an array.
64
140
  * Enhancements to GandiV5::LiveDNS::Zone::Snapshot
65
141
  * Add .list
data/README.md CHANGED
@@ -1,18 +1,21 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/gandi_v5.png)](http://badge.fury.io/rb/gandi_v5)
2
- [![Build Status](https://secure.travis-ci.org/robertgauld/gandi_v5.png?branch=master)](http://travis-ci.org/robertgauld/gandi_v5)
3
- [![Coveralls Status](https://coveralls.io/repos/robertgauld/gandi_v5/badge.png?branch=master)](https://coveralls.io/r/robertgauld/gandi_v5)
4
- [![Code Climate](https://codeclimate.com/github/robertgauld/gandi_v5.png?branch=master)](https://codeclimate.com/github/robertgauld/gandi_v5)
5
- [![security](https://hakiri.io/github/robertgauld/gandi_v5/master.svg)](https://hakiri.io/github/robertgauld/gandi_v5/master)
2
+ [![Commit Checks](https://github.com/robertgauld/gandi_v5/workflows/Commit%20Checks/badge.svg)](https://github.com/robertgauld/gandi_v5/actions?query=workflow%3A%22Commit+Checks%22)
3
+ [![Coveralls Status](https://coveralls.io/repos/robertgauld/gandi_v5/badge.png?branch=main)](https://coveralls.io/r/robertgauld/gandi_v5)
4
+ [![Code Climate](https://codeclimate.com/github/robertgauld/gandi_v5.png?branch=main)](https://codeclimate.com/github/robertgauld/gandi_v5)
6
5
 
7
6
  ## Ruby Versions
8
7
  This gem supports the following versions of ruby, it may work on other versions but is not tested against them so don't rely on it.
9
8
 
10
9
  * ruby:
11
10
  * 2.6.0 - 2.6.6
12
- * 2.7.0 - 2.7.1
13
- * truffleruby 20.1.0
14
- * jruby, once it's reached parity with ruby 2.6.x
15
- * rubinius, once it's reached parity with ruby 2.6.x
11
+ * 2.7.0 - 2.7.2
12
+ * 3.0.0
13
+ * truffleruby 20.1.0 - 20.3.0
14
+
15
+ This gem doesn't yet support the following versions of ruby, although hopefully it soon will.
16
+
17
+ * jruby - not yet at parity with ruby 2.6.x
18
+ * rubinius - not yet at parity with ruby 2.6.x
16
19
 
17
20
 
18
21
  ## Gandi V5
@@ -25,23 +28,24 @@ Gandi say: **_"Please note that this API is currently in BETA testing, so care s
25
28
 
26
29
  But then you were going to be careful anyway as this gem is currently in the version 0.something range weren't you!
27
30
 
28
- Details of the API can be found at:
31
+ Details of Gandi's API can be found at:
29
32
 
30
33
  * <https://api.gandi.net/docs/>
31
34
  * <https://doc.livedns.gandi.net/>
32
35
 
36
+ Details of the gem's API can be found at <https://rubydoc.info/github/robertgauld/gandi_v5/main>
33
37
 
34
38
  ## Installation
35
39
 
36
40
  If you're using bundler then add it to your Gemfile and run the bundle command.
37
41
 
38
42
  ```ruby
39
- gem 'gandi_v5', '~> 0.1'
43
+ gem 'gandi_v5', '~> 0.10'
40
44
  ```
41
45
 
42
46
  If you're not using bundler then install it from the command line.
43
47
  ```bash
44
- gem install gandi_v5 -v '~> 0.1'
48
+ gem install gandi_v5 -v '~> 0.10'
45
49
  ```
46
50
 
47
51
  ## Usage
@@ -58,6 +62,52 @@ GandiV5.api_key = '…' # Unless you've set it in the environment variable GANDI
58
62
 
59
63
  ### Examples
60
64
 
65
+ #### List renewal dates and costs for all domains
66
+ ```ruby
67
+ # For each domain (sorted by assending renewal date) print <date>\t<cost>\t<fqdn>
68
+ GandiV5::Domain.list.each do |domain|
69
+ puts [
70
+ domain.dates.registry_ends_at.to_date,
71
+ "£#{domain.renewal_price.price_after_taxes}",
72
+ domain.fqdn
73
+ ].join("\t")
74
+ end
75
+ ```
76
+
77
+ #### List email addresses for all domains
78
+
79
+ ```ruby
80
+ # For each domain:
81
+ # 1. Create an empty hash to store address => description
82
+ # 2. Get the mailboxes and add them to the hash
83
+ # 3. Get the forwards and add them to the hash
84
+ # 4. Sort the hash by email address
85
+ # 5. Print the list
86
+ GandiV5::Domain.list.each do |domain|
87
+ emails = {}
88
+
89
+ mailboxes = GandiV5::Email::Mailbox.list(domain.fqdn)
90
+ mailboxes.each do |mailbox|
91
+ mailbox.refresh
92
+ emails["#{mailbox.login}@#{domain.fqdn}"] = "#{mailbox.type} mailbox " \
93
+ "(#{mailbox.quota_usage.to_i}% " \
94
+ "of #{(mailbox.quota / 1024**3).round}GB used)"
95
+ mailbox.aliases.each do |alias_name|
96
+ emails["#{alias_name}@#{domain.fqdn}"] = "alias for #{mailbox.login}@#{domain.fqdn}"
97
+ end
98
+ end
99
+
100
+ forwards = GandiV5::Email::Forward.list(domain.fqdn)
101
+ forwards.each do |forward|
102
+ emails["#{forward.source}@#{domain.fqdn}"] = "forwards to #{forward.destinations.join(', ')}"
103
+ end
104
+
105
+ emails.sort.each do |address, text|
106
+ puts "#{address}\t#{text}"
107
+ end
108
+ end
109
+ ```
110
+
61
111
  #### Domains
62
112
 
63
113
  ```ruby
@@ -68,15 +118,16 @@ domains = GandiV5.domains
68
118
  domains.map!(&:refresh)
69
119
  ```
70
120
 
71
- TODO: More examples!
72
-
73
-
74
121
  ## Versioning
75
122
 
76
123
  We follow the [Semantic Versioning](http://semver.org/) concept.
77
124
 
78
125
  | Gem Version | Gandi API Release Date |
79
126
  | --------------- | ------------------------ |
127
+ | 0.10.0 | 2020-12-10 |
128
+ | 0.9.0 | 2020-07-29 |
129
+ | 0.8.0 | 2020-07-10 |
130
+ | 0.7.0 | 2020-05-07 |
80
131
  | 0.6.0 | 2020-05-07 (not LiveDNS) |
81
132
  | 0.5.0 | 2019-10-01 |
82
133
  | 0.4.0 | 2019-10-01 |
@@ -5,14 +5,17 @@ require 'securerandom'
5
5
  require 'zeitwerk'
6
6
 
7
7
  # Custom inflector for Zeitwerk.
8
+ # @api private
8
9
  class MyInflector < Zeitwerk::Inflector
9
10
  # Convert file's base name to class name when
10
11
  # Zeitwerk's included inflector gets it wrong.
11
12
  # @param basename [String] the file's base name (no path or extension)
12
- # @param abspath [String] the file's absolute path
13
+ # @param _abspath [String] the file's absolute path
13
14
  # @return [String] the class name
14
15
  def camelize(basename, _abspath)
15
16
  case basename
17
+ when 'dns_record'
18
+ 'DNSRecord'
16
19
  when 'live_dns'
17
20
  'LiveDNS'
18
21
  when 'tld'
@@ -31,32 +34,37 @@ loader.setup
31
34
 
32
35
  # Namespace for classes which access the Gandi V5 API.
33
36
  # Also provides useful methods and constants for them.
34
- # This is where you configure the gem:
35
- # * Setting your Gandi API key:
36
- # 1. Get your API key - Login to Gandi and visit User Settings ->
37
- # Change password & configure access restrictions.
37
+ # To get your API key login to Gandi and visit
38
+ # "User Settings" -> "Change password & configure access restrictions".
39
+ # Set your API key either in the GANDI_API_KEY environment variable or
40
+ # by setting the api_key class attribute.
38
41
  # @see https://api.gandi.net/docs/
39
42
  # @see https://doc.livedns.gandi.net/
40
43
  # @!attribute [w] api_key
41
44
  # @return [String]
42
45
  class GandiV5
46
+ # Base URL for all API requests.
43
47
  BASE = 'https://api.gandi.net/v5/'
44
48
 
49
+ # Get information on a domain.
45
50
  # @see GandiV5::Domain.fetch
46
51
  def self.domain(fqdn)
47
52
  GandiV5::Domain.fetch(fqdn)
48
53
  end
49
54
 
55
+ # Get information on all domains.
50
56
  # @see GandiV5::Domain.list
51
57
  def self.domains(**params)
52
58
  GandiV5::Domain.list(**params)
53
59
  end
54
60
 
61
+ # List mailboxes for a domain.
55
62
  # @see GandiV5::Email::Mailbox.list
56
63
  def self.mailboxes(fqdn, **params)
57
64
  GandiV5::Email::Mailbox.list(fqdn, **params)
58
65
  end
59
66
 
67
+ # List email slots for a domain.
60
68
  # @see GandiV5::Email::Slot.list
61
69
  def self.mailbox_slots(fqdn)
62
70
  GandiV5::Email::Slot.list(fqdn)
@@ -65,15 +73,21 @@ class GandiV5
65
73
  class << self
66
74
  attr_writer :api_key
67
75
 
68
- # Might raise:
69
- # * RestClient::NotFound
70
- # * RestClient::Unauthorized
71
- # Bad authentication attempt because of a wrong API Key.
72
- # * RestClient::Forbidden
73
- # Access to the resource is denied.
74
- # Mainly due to a lack of permissions to access it.
75
- # * GandiV5::Error
76
- # * JSON::ParserError
76
+ # Make a GET request to a Gandi end point.
77
+ # @param url [String, #to_s]
78
+ # the full URL (including GandiV5::BASE) to fetch.
79
+ # @param headers [Hash{String, Symbol, #to_s => String, Symbol, #to_s}]
80
+ # the headers to send in the request, the authorisation will be added.
81
+ # @return [Array<(RestClient::Response, Object)>]
82
+ # The response from the server and the result of parsing the responce's body.
83
+ # @raise [RestClient::NotFound]
84
+ # @raise [RestClient::Unauthorized]
85
+ # Bad authentication attempt because of a wrong API Key.
86
+ # @raise [RestClient::Forbidden]
87
+ # Access to the resource is denied.
88
+ # Mainly due to a lack of permissions to access it.
89
+ # @raise [GandiV5::Error]
90
+ # @raise [JSON::ParserError]
77
91
  def get(url, **headers)
78
92
  prepare_headers headers, url
79
93
  response = RestClient.get url, **headers
@@ -82,16 +96,59 @@ class GandiV5
82
96
  handle_bad_request(e)
83
97
  end
84
98
 
85
- # Might raise:
86
- # * RestClient::NotFound
87
- # * RestClient::Unauthorized
88
- # Bad authentication attempt because of a wrong API Key.
89
- # * RestClient::Forbidden
90
- # Access to the resource is denied.
91
- # Mainly due to a lack of permissions to access it.
92
- # * RestClient::Conflict
93
- # * GandiV5::Error
94
- # * JSON::ParserError
99
+ # Make a GET request to a paginated end point at Gandi.
100
+ # @param url [String, #to_s]
101
+ # the full URL (including GandiV5::BASE) to fetch.
102
+ # @param page [#each, Integer] the page/pages of results to get.
103
+ # @param per_page [Integer, #to_s] the number of items to get per page of results.
104
+ # @param headers [Hash{String, Symbol, #to_s => String, Symbol, #to_s}]
105
+ # the headers to send in the request, the authorisation will be added.
106
+ # @return [Array<(RestClient::Response, Object)>]
107
+ # The response from the server and the result of parsing the responce's body.
108
+ # @raise [RestClient::NotFound]
109
+ # @raise [RestClient::Unauthorized]
110
+ # Bad authentication attempt because of a wrong API Key.
111
+ # @raise [RestClient::Forbidden]
112
+ # Access to the resource is denied.
113
+ # Mainly due to a lack of permissions to access it.
114
+ # @raise [GandiV5::Error]
115
+ # @raise [JSON::ParserError]
116
+ def paginated_get(url, page = (1..), per_page = 100, **headers)
117
+ unless page.respond_to?(:each)
118
+ fail ArgumentError, 'page must be positive' unless page.positive?
119
+
120
+ page = [page]
121
+ end
122
+
123
+ headers[:params] ||= {}
124
+ headers[:params].transform_keys!(&:to_s)
125
+ headers[:params]['per_page'] = per_page
126
+
127
+ page.each do |page_number|
128
+ headers[:params]['page'] = page_number
129
+ _resp, this_data = get(url, **headers)
130
+ break if this_data.empty?
131
+
132
+ yield this_data
133
+ break if this_data.count < per_page
134
+ end
135
+ end
136
+
137
+ # Make a DELETE request to a Gandi end point.
138
+ # @param url [String, #to_s]
139
+ # the full URL (including GandiV5::BASE) to fetch.
140
+ # @param headers [Hash{String, Symbol, #to_s => String, Symbol, #to_s}]
141
+ # the headers to send in the request, the authorisation will be added.
142
+ # @return [Array<(RestClient::Response, Object)>]
143
+ # The response from the server and the result of parsing the responce's body.
144
+ # @raise [RestClient::NotFound]
145
+ # @raise [RestClient::Unauthorized]
146
+ # Bad authentication attempt because of a wrong API Key.
147
+ # @raise [RestClient::Forbidden]
148
+ # Access to the resource is denied.
149
+ # Mainly due to a lack of permissions to access it.
150
+ # @raise [GandiV5::Error]
151
+ # @raise [JSON::ParserError]
95
152
  def delete(url, **headers)
96
153
  prepare_headers headers, url
97
154
  response = RestClient.delete url, **headers
@@ -103,17 +160,24 @@ class GandiV5
103
160
  handle_bad_request(e)
104
161
  end
105
162
 
106
- # Might raise:
107
- # * RestClient::NotFound
108
- # * RestClient::Unauthorized
109
- # Bad authentication attempt because of a wrong API Key.
110
- # * RestClient::Forbidden
111
- # Access to the resource is denied.
112
- # Mainly due to a lack of permissions to access it.
113
- # * RestClient::BadRequest
114
- # * RestClient::Conflict
115
- # * GandiV5::Error
116
- # * JSON::ParserError
163
+ # Make a PATCH request to a Gandi end point.
164
+ # @param url [String, #to_s]
165
+ # the full URL (including GandiV5::BASE) to fetch.
166
+ # @param payload [String, #to_s] the body for the request.
167
+ # @param headers [Hash{String, Symbol, #to_s => String, Symbol, #to_s}]
168
+ # the headers to send in the request, the authorisation will be added.
169
+ # @return [Array<(RestClient::Response, Object)>]
170
+ # The response from the server and the result of parsing the responce's body.
171
+ # @raise [RestClient::NotFound]
172
+ # @raise [RestClient::Unauthorized]
173
+ # Bad authentication attempt because of a wrong API Key.
174
+ # @raise [RestClient::Forbidden]
175
+ # Access to the resource is denied.
176
+ # Mainly due to a lack of permissions to access it.
177
+ # @raise [RestClient::BadRequest]
178
+ # @raise [RestClient::Conflict]
179
+ # @raise [GandiV5::Error]
180
+ # @raise [JSON::ParserError]
117
181
  def patch(url, payload = '', **headers)
118
182
  prepare_headers headers, url
119
183
  headers[:'content-type'] ||= 'application/json'
@@ -123,17 +187,24 @@ class GandiV5
123
187
  handle_bad_request(e)
124
188
  end
125
189
 
126
- # Might raise:
127
- # * RestClient::NotFound
128
- # * RestClient::Unauthorized
129
- # Bad authentication attempt because of a wrong API Key.
130
- # * RestClient::Forbidden
131
- # Access to the resource is denied.
132
- # Mainly due to a lack of permissions to access it.
133
- # * RestClient::BadRequest
134
- # * RestClient::Conflict
135
- # * GandiV5::Error
136
- # * JSON::ParserError
190
+ # Make a POST request to a Gandi end point.
191
+ # @param url [String, #to_s]
192
+ # the full URL (including GandiV5::BASE) to fetch.
193
+ # @param payload [String, #to_s] the body for the request.
194
+ # @param headers [Hash{String, Symbol, #to_s => String, Symbol, #to_s}]
195
+ # the headers to send in the request, the authorisation will be added.
196
+ # @return [Array<(RestClient::Response, Object)>]
197
+ # The response from the server and the result of parsing the responce's body.
198
+ # @raise [RestClient::NotFound]
199
+ # @raise [RestClient::Unauthorized]
200
+ # Bad authentication attempt because of a wrong API Key.
201
+ # @raise [RestClient::Forbidden]
202
+ # Access to the resource is denied.
203
+ # Mainly due to a lack of permissions to access it.
204
+ # @raise [RestClient::BadRequest]
205
+ # @raise [RestClient::Conflict]
206
+ # @raise [GandiV5::Error]
207
+ # @raise [JSON::ParserError]
137
208
  def post(url, payload = '', **headers)
138
209
  prepare_headers headers, url
139
210
  headers[:'content-type'] ||= 'application/json'
@@ -143,17 +214,24 @@ class GandiV5
143
214
  handle_bad_request(e)
144
215
  end
145
216
 
146
- # Might raise:
147
- # * RestClient::NotFound
148
- # * RestClient::Unauthorized
149
- # Bad authentication attempt because of a wrong API Key.
150
- # * RestClient::Forbidden
151
- # Access to the resource is denied.
152
- # Mainly due to a lack of permissions to access it.
153
- # * RestClient::BadRequest
154
- # * RestClient::Conflict
155
- # * GandiV5::Error
156
- # * JSON::ParserError
217
+ # Make a PUT request to a Gandi end point.
218
+ # @param url [String, #to_s]
219
+ # the full URL (including GandiV5::BASE) to fetch.
220
+ # @param payload [String, #to_s] the body for the request.
221
+ # @param headers [Hash{String, Symbol, #to_s => String, Symbol, #to_s}]
222
+ # the headers to send in the request, the authorisation will be added
223
+ # @return [Array<(RestClient::Response, Object)>]
224
+ # The response from the server and the result of parsing the responce's body.
225
+ # @raise [RestClient::NotFound]
226
+ # @raise [RestClient::Unauthorized]
227
+ # Bad authentication attempt because of a wrong API Key.
228
+ # @raise [RestClient::Forbidden]
229
+ # Access to the resource is denied.
230
+ # Mainly due to a lack of permissions to access it.
231
+ # @raise [RestClient::BadRequest]
232
+ # @raise [RestClient::Conflict]
233
+ # @raise [GandiV5::Error]
234
+ # @raise [JSON::ParserError]
157
235
  def put(url, payload = '', **headers)
158
236
  prepare_headers headers, url
159
237
  headers[:'content-type'] ||= 'application/json'
@@ -169,16 +247,6 @@ class GandiV5
169
247
  @api_key ||= ENV.fetch('GANDI_API_KEY')
170
248
  end
171
249
 
172
- def authorisation_header(url)
173
- if url.start_with?(BASE)
174
- { Authorization: "Apikey #{api_key}" }
175
- elsif url.start_with?(GandiV5::LiveDNS::BASE)
176
- { 'X-Api-Key': api_key }
177
- else
178
- fail ArgumentError, "Don't know how to authorise for url: #{url}"
179
- end
180
- end
181
-
182
250
  def parse_response(response)
183
251
  type = response.headers.fetch(:content_type).split(';').first.chomp
184
252
  case type
@@ -196,10 +264,11 @@ class GandiV5
196
264
  end
197
265
  end
198
266
 
199
- def prepare_headers(headers, url)
200
- headers.transform_keys!(&:to_sym)
267
+ def prepare_headers(headers, _url)
268
+ headers.transform_keys! { |key| key.to_s.downcase.to_sym }
201
269
  headers[:accept] ||= 'application/json'
202
- headers.merge!(authorisation_header(url))
270
+ headers[:authorization] = "Apikey #{api_key}"
271
+ headers
203
272
  end
204
273
 
205
274
  def handle_bad_request(exception)