gandi_v5 0.5.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -5
  3. data/LICENSE.md +2 -6
  4. data/README.md +67 -18
  5. data/lib/gandi_v5.rb +137 -70
  6. data/lib/gandi_v5/billing/info/prepaid.rb +1 -0
  7. data/lib/gandi_v5/data.rb +3 -2
  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 +3 -2
  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 +4 -10
  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 +9 -9
  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/domain/transfer_in/availability_spec.rb +49 -0
  62. data/spec/units/gandi_v5/domain/transfer_in_spec.rb +143 -0
  63. data/spec/units/gandi_v5/domain_spec.rb +13 -39
  64. data/spec/units/gandi_v5/email/forward_spec.rb +5 -34
  65. data/spec/units/gandi_v5/email/mailbox_spec.rb +4 -34
  66. data/spec/units/gandi_v5/email/slot_spec.rb +10 -2
  67. data/spec/units/gandi_v5/live_dns/domain/dnssec_key_spec.rb +128 -0
  68. data/spec/units/gandi_v5/live_dns/{record_set_spec.rb → domain/record_spec.rb} +1 -1
  69. data/spec/units/gandi_v5/live_dns/domain/snapshot_spec.rb +101 -0
  70. data/spec/units/gandi_v5/live_dns/domain/tsig_key_spec.rb +78 -0
  71. data/spec/units/gandi_v5/live_dns/domain_spec.rb +297 -118
  72. data/spec/units/gandi_v5/live_dns_spec.rb +0 -12
  73. data/spec/units/gandi_v5/sharing_space_spec.rb +4 -0
  74. data/spec/units/gandi_v5/simple_hosting/instance/application_spec.rb +37 -0
  75. data/spec/units/gandi_v5/simple_hosting/instance/database_spec.rb +4 -0
  76. data/spec/units/gandi_v5/simple_hosting/instance/language_spec.rb +4 -0
  77. data/spec/units/gandi_v5/simple_hosting/instance/upgrade_spec.rb +4 -0
  78. data/spec/units/gandi_v5/simple_hosting/instance/virtual_host/linked_dns_zone_spec.rb +50 -0
  79. data/spec/units/gandi_v5/simple_hosting/instance/virtual_host_spec.rb +199 -0
  80. data/spec/units/gandi_v5/simple_hosting/instance_spec.rb +182 -0
  81. data/spec/units/gandi_v5/simple_hosting_spec.rb +9 -0
  82. data/spec/units/gandi_v5_spec.rb +111 -14
  83. metadata +174 -53
  84. data/.gitignore +0 -26
  85. data/.rspec +0 -3
  86. data/.rubocop.yml +0 -30
  87. data/.travis.yml +0 -38
  88. data/FUNDING.yml +0 -10
  89. data/Gemfile +0 -6
  90. data/Guardfile +0 -39
  91. data/Rakefile +0 -3
  92. data/bin/console +0 -13
  93. data/gandi_v5.gemspec +0 -42
  94. data/lib/gandi_v5/domain/sharing_space.rb +0 -21
  95. data/lib/gandi_v5/live_dns/has_zone_records.rb +0 -153
  96. data/lib/gandi_v5/live_dns/record_set.rb +0 -79
  97. data/lib/gandi_v5/live_dns/zone.rb +0 -160
  98. data/lib/gandi_v5/live_dns/zone/snapshot.rb +0 -81
  99. data/spec/features/domain_spec.rb +0 -45
  100. data/spec/features/livedns_domain_spec.rb +0 -8
  101. data/spec/features/livedns_zone_spec.rb +0 -44
  102. data/spec/features/mailbox_spec.rb +0 -18
  103. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/fetch.yml +0 -11
  104. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/list.yml +0 -11
  105. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/list.yml +0 -3
  106. data/spec/fixtures/vcr/Domain_features/List_domains.yml +0 -55
  107. data/spec/fixtures/vcr/Domain_features/Renew_domain.yml +0 -133
  108. data/spec/fixtures/vcr/LiveDNS_Domain_features/List_domains.yml +0 -32
  109. data/spec/fixtures/vcr/LiveDNS_Zone_features/List_zones.yml +0 -42
  110. data/spec/fixtures/vcr/LiveDNS_Zone_features/Make_and_save_snapshot.yml +0 -72
  111. data/spec/fixtures/vcr/LiveDNS_Zone_features/Save_zone_to_file.yml +0 -28
  112. data/spec/fixtures/vcr/Mailbox_features/List_mailboxes.yml +0 -39
  113. data/spec/units/gandi_v5/domain/sharing_space_spec.rb +0 -4
  114. data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +0 -66
  115. 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: eac7a49d78a12be6f28ce2a12aab37a8fcbe25e24ffd40f215a7bf088df81125
4
- data.tar.gz: bb0e28904dc4869a6846c6cd4204b7c9c9e97937f9a1d7ef9dcbf1ceef7b7ea2
3
+ metadata.gz: 4bfa3d695cec03737e8e5c3639c7744300babd00d59081f4edf14f013d2e9787
4
+ data.tar.gz: ce687383ed1d014889d22e9d33a068dad8a8dc8ec2a73a38c9150014195a3f0b
5
5
  SHA512:
6
- metadata.gz: 3fa831c1c527c6b06f97627d36ba3085586f5675690ff120a075f9a88a24bde2493d83c4b7b04803e00295459af2a49f92e049f0172af288634c04d32d4c1f6c
7
- data.tar.gz: 7116bae0e14637e37ff361e530d711a3d2d68177554df107963a020049746b955cc9cfbb61e9dca5ad354ced47b5d88d4c3047ec2a3b7f9d4bf8005426b1ebdc
6
+ metadata.gz: a2752f84704fbd326503b2bada3e3193d2215abc6c19e1b71198b29eabaf4e67f473249d076aa806ca2c937195a35c7d2a8c490e1f586d0c3f121be5900c1ae5
7
+ data.tar.gz: 398dc026b251a700432dee898e23c207bee4fa10c5bcc879f706f0e9c0ed0793d3b670861b97221bd4f64bfbfd27c32a589b5b7eeb911662b95623461ec90f59
@@ -1,5 +1,69 @@
1
1
  # Gandi V5 API Gem Changelog
2
2
 
3
+ ## Version 0.9.1
4
+
5
+ * Add testing against ruby 2.7.2 and 3.0.0
6
+
7
+ ## Version 0.9.0
8
+
9
+ * 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):
10
+ * GandiV5::Domain::TransferIn:
11
+ * .create(fqdn, \*\*options)
12
+ * .fetch(fqdn)
13
+ * .relaunch(fqdn)
14
+ * .resend_foa_emails(fqdn, email_address)
15
+ * \#relaunch
16
+ * \#resend_foa_emails(email_address)
17
+ * GandiV5::Domain::TransferIn::Availabillity:
18
+ * .fetch(fqdn, auth_code = nil)
19
+ * Documentation improvements
20
+
21
+ ## Version 0.8.0
22
+
23
+ * Domain:
24
+ * .list - add resellee_id filter
25
+ * 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)
26
+ * SimpleHosting::Instance
27
+ * SimpleHosting::Instance::VirtualHost
28
+ * SimpleHosting::Instance::Application
29
+ * SimpleHosting::Instance::Database
30
+ * SimpleHosting::Instance::Language
31
+ * SimpleHosting::Instance::Upgrade
32
+ * GandiV5::Domain::SharingSpace moved to GandiV5::SharingSpace
33
+
34
+ ## Version 0.7.0
35
+
36
+ * LiveDNS:
37
+ * Rename LiveDNS::RecordSet to LiveDNS::Domain::Record
38
+ * Domains:
39
+ * .list now returns an array of strings
40
+ * Can no longer change the zone used by a domain
41
+ * Added automatic_snapshots attribute for whether snapshots are automatically created when a modification is made to this domain's records
42
+ * \#replace_records and \#replace_records_for merged into \#replace_records
43
+ * If replacing with a zone file use the new #replace_zone_lines
44
+ * Added:
45
+ * .create
46
+ * .record_types
47
+ * .generic_name_servers(fqdn)
48
+ * \#name_servers and #fetch_name_servers
49
+ * \#tsig_keys, #fetch_tsig_keys, \#add_tsig_key, \#remove_tsig_key
50
+ * \#axfr_clients, #fetch_axfr_clients, #add_axfr_client, \#remove_axfr_client
51
+ * ::DnssecKeys, #dnssec_keys, #fetch_dnssec_keys
52
+ * Snapshots:
53
+ * Moved to live under LiveDNS::Domain not LiveDNS::Zone
54
+ * Are now accessed via the fully qualified domain name NOT the zone's UUID
55
+ * Ability to access the zone from a snapshot is removed
56
+ * Taking a snapshot now allows for named snapshots
57
+ * Added automatic attribute for when a snapshot was taken due to a zone change
58
+ * .list now returns an array of snapshots (records are fetched in a seperate request when first needed)
59
+ * Zone removed.
60
+
61
+ ## Version 0.6.0
62
+
63
+ * GandiV5::Email::Slot.create now supports sharing_id
64
+ * GandiV5::Email::Slot.create's type argument is now named not positional
65
+ * Add reseller information to GandiV5::Domain
66
+
3
67
  ## Version 0.5.0
4
68
 
5
69
  * Add support for truffleruby 20.1.0
@@ -33,11 +97,11 @@
33
97
  ## Version 0.2.0
34
98
 
35
99
  * Enhancements to GandiV5::Domain
36
- * .availability(fqdn, **options) moved to GandiV5::Domain::Availability.fetch(fqdn, **options)
100
+ * .availability(fqdn, \*\*options) moved to GandiV5::Domain::Availability.fetch(fqdn, \*\*options)
37
101
  * .create now returns created domain (except in dry-run mode)
38
102
  * .tlds moved to GandiV5::Domain::TLD.list
39
103
  * .tld(name) moved to GandiV5::Domain::TLD.fetch(name)
40
- * #renewal_price(currency: 'GBP', period: 1) added
104
+ * \#renewal_price(currency: 'GBP', period: 1) added
41
105
  * Enhancements to GandiV5::Email::Mailbox
42
106
  * .create now returns created mailbox
43
107
  * .create now checks for available slots and a valid type has been passed
@@ -46,14 +110,14 @@
46
110
  * Add #disable to disable the auto responder in Gandi
47
111
  * Enhancements to GandiV5::Email::Slot
48
112
  * .create now returns created slot
49
- * #delete now checks for inactiveness and refundableness
113
+ * \#delete now checks for inactiveness and refundableness
50
114
  * Enhancements to GandiV5::LiveDNS::Domain
51
115
  * Add #zone and #fetch_zone
52
- * Remove #replace_*_records_for methods
116
+ * Remove #replace_\*_records_for methods
53
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.
54
118
  * Enhancements to GandiV5::LiveDNS::Zone
55
119
  * .create now returns created zone
56
- * Remove #replace_*_records_for methods
120
+ * Remove #replace_\*_records_for methods
57
121
  * 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.
58
122
  * Enhancements to GandiV5::LiveDNS::Zone::Snapshot
59
123
  * 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,16 +1,16 @@
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.
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
11
+ * 2.7.0 - 2.7.2
12
+ * 3.0.0
13
+ * truffleruby 20.1.0 - 20.2.0
14
14
  * jruby, once it's reached parity with ruby 2.6.x
15
15
  * rubinius, once it's reached parity with ruby 2.6.x
16
16
 
@@ -25,23 +25,24 @@ Gandi say: **_"Please note that this API is currently in BETA testing, so care s
25
25
 
26
26
  But then you were going to be careful anyway as this gem is currently in the version 0.something range weren't you!
27
27
 
28
- Details of the API can be found at:
28
+ Details of Gandi's API can be found at:
29
29
 
30
30
  * <https://api.gandi.net/docs/>
31
31
  * <https://doc.livedns.gandi.net/>
32
32
 
33
+ Details of the gem's API can be found at <https://rubydoc.info/github/robertgauld/gandi_v5/main>
33
34
 
34
35
  ## Installation
35
36
 
36
37
  If you're using bundler then add it to your Gemfile and run the bundle command.
37
38
 
38
39
  ```ruby
39
- gem 'gandi_v5', '~> 0.1'
40
+ gem 'gandi_v5', '~> 0.8'
40
41
  ```
41
42
 
42
43
  If you're not using bundler then install it from the command line.
43
44
  ```bash
44
- gem install gandi_v5 -v '~> 0.1'
45
+ gem install gandi_v5 -v '~> 0.8'
45
46
  ```
46
47
 
47
48
  ## Usage
@@ -58,6 +59,52 @@ GandiV5.api_key = '…' # Unless you've set it in the environment variable GANDI
58
59
 
59
60
  ### Examples
60
61
 
62
+ #### List renewal dates and costs for all domains
63
+ ```ruby
64
+ # For each domain (sorted by assending renewal date) print <date>\t<cost>\t<fqdn>
65
+ GandiV5::Domain.list.each do |domain|
66
+ puts [
67
+ domain.dates.registry_ends_at.to_date,
68
+ "£#{domain.renewal_price.price_after_taxes}",
69
+ domain.fqdn
70
+ ].join("\t")
71
+ end
72
+ ```
73
+
74
+ #### List email addresses for all domains
75
+
76
+ ```ruby
77
+ # For each domain:
78
+ # 1. Create an empty hash to store address => description
79
+ # 2. Get the mailboxes and add them to the hash
80
+ # 3. Get the forwards and add them to the hash
81
+ # 4. Sort the hash by email address
82
+ # 5. Print the list
83
+ GandiV5::Domain.list.each do |domain|
84
+ emails = {}
85
+
86
+ mailboxes = GandiV5::Email::Mailbox.list(domain.fqdn)
87
+ mailboxes.each do |mailbox|
88
+ mailbox.refresh
89
+ emails["#{mailbox.login}@#{domain.fqdn}"] = "#{mailbox.type} mailbox " \
90
+ "(#{mailbox.quota_usage.to_i}% " \
91
+ "of #{(mailbox.quota / 1024**3).round}GB used)"
92
+ mailbox.aliases.each do |alias_name|
93
+ emails["#{alias_name}@#{domain.fqdn}"] = "alias for #{mailbox.login}@#{domain.fqdn}"
94
+ end
95
+ end
96
+
97
+ forwards = GandiV5::Email::Forward.list(domain.fqdn)
98
+ forwards.each do |forward|
99
+ emails["#{forward.source}@#{domain.fqdn}"] = "forwards to #{forward.destinations.join(', ')}"
100
+ end
101
+
102
+ emails.sort.each do |address, text|
103
+ puts "#{address}\t#{text}"
104
+ end
105
+ end
106
+ ```
107
+
61
108
  #### Domains
62
109
 
63
110
  ```ruby
@@ -68,19 +115,21 @@ domains = GandiV5.domains
68
115
  domains.map!(&:refresh)
69
116
  ```
70
117
 
71
- TODO: More examples!
72
-
73
-
74
118
  ## Versioning
75
119
 
76
120
  We follow the [Semantic Versioning](http://semver.org/) concept.
77
121
 
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 |
122
+ | Gem Version | Gandi API Release Date |
123
+ | --------------- | ------------------------ |
124
+ | 0.9.0 | 2020-07-29 |
125
+ | 0.8.0 | 2020-07-10 |
126
+ | 0.7.0 | 2020-05-07 |
127
+ | 0.6.0 | 2020-05-07 (not LiveDNS) |
128
+ | 0.5.0 | 2019-10-01 |
129
+ | 0.4.0 | 2019-10-01 |
130
+ | 0.3.0 | 2019-08-22 |
131
+ | 0.2.0 | 2019-05-16 |
132
+ | 0.1.0 | 2019-05-16 |
84
133
 
85
134
  See <https://api.gandi.net/docs/reference#API-Changelog> to find out what
86
135
  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
@@ -31,32 +32,37 @@ loader.setup
31
32
 
32
33
  # Namespace for classes which access the Gandi V5 API.
33
34
  # 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.
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.
38
39
  # @see https://api.gandi.net/docs/
39
40
  # @see https://doc.livedns.gandi.net/
40
41
  # @!attribute [w] api_key
41
42
  # @return [String]
42
43
  class GandiV5
44
+ # Base URL for all API requests.
43
45
  BASE = 'https://api.gandi.net/v5/'
44
46
 
47
+ # Get information on a domain.
45
48
  # @see GandiV5::Domain.fetch
46
49
  def self.domain(fqdn)
47
50
  GandiV5::Domain.fetch(fqdn)
48
51
  end
49
52
 
53
+ # Get information on all domains.
50
54
  # @see GandiV5::Domain.list
51
55
  def self.domains(**params)
52
56
  GandiV5::Domain.list(**params)
53
57
  end
54
58
 
59
+ # List mailboxes for a domain.
55
60
  # @see GandiV5::Email::Mailbox.list
56
61
  def self.mailboxes(fqdn, **params)
57
62
  GandiV5::Email::Mailbox.list(fqdn, **params)
58
63
  end
59
64
 
65
+ # List email slots for a domain.
60
66
  # @see GandiV5::Email::Slot.list
61
67
  def self.mailbox_slots(fqdn)
62
68
  GandiV5::Email::Slot.list(fqdn)
@@ -65,15 +71,21 @@ class GandiV5
65
71
  class << self
66
72
  attr_writer :api_key
67
73
 
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
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]
77
89
  def get(url, **headers)
78
90
  prepare_headers headers, url
79
91
  response = RestClient.get url, **headers
@@ -82,16 +94,59 @@ class GandiV5
82
94
  handle_bad_request(e)
83
95
  end
84
96
 
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
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]
95
150
  def delete(url, **headers)
96
151
  prepare_headers headers, url
97
152
  response = RestClient.delete url, **headers
@@ -103,17 +158,24 @@ class GandiV5
103
158
  handle_bad_request(e)
104
159
  end
105
160
 
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
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]
117
179
  def patch(url, payload = '', **headers)
118
180
  prepare_headers headers, url
119
181
  headers[:'content-type'] ||= 'application/json'
@@ -123,17 +185,24 @@ class GandiV5
123
185
  handle_bad_request(e)
124
186
  end
125
187
 
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
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]
137
206
  def post(url, payload = '', **headers)
138
207
  prepare_headers headers, url
139
208
  headers[:'content-type'] ||= 'application/json'
@@ -143,17 +212,24 @@ class GandiV5
143
212
  handle_bad_request(e)
144
213
  end
145
214
 
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
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]
157
233
  def put(url, payload = '', **headers)
158
234
  prepare_headers headers, url
159
235
  headers[:'content-type'] ||= 'application/json'
@@ -169,16 +245,6 @@ class GandiV5
169
245
  @api_key ||= ENV.fetch('GANDI_API_KEY')
170
246
  end
171
247
 
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
248
  def parse_response(response)
183
249
  type = response.headers.fetch(:content_type).split(';').first.chomp
184
250
  case type
@@ -196,10 +262,11 @@ class GandiV5
196
262
  end
197
263
  end
198
264
 
199
- def prepare_headers(headers, url)
200
- headers.transform_keys!(&:to_sym)
265
+ def prepare_headers(headers, _url)
266
+ headers.transform_keys! { |key| key.to_s.downcase.to_sym }
201
267
  headers[:accept] ||= 'application/json'
202
- headers.merge!(authorisation_header(url))
268
+ headers[:authorization] = "Apikey #{api_key}"
269
+ headers
203
270
  end
204
271
 
205
272
  def handle_bad_request(exception)