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