gandi_v5 0.6.0 → 0.10.0

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