gandi_v5 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +44 -2
  5. data/Guardfile +5 -6
  6. data/README.md +5 -5
  7. data/doc/GandiV5/Billing/Info/Prepaid.html +817 -0
  8. data/doc/GandiV5/Billing/Info.html +641 -0
  9. data/doc/GandiV5/Billing.html +293 -0
  10. data/doc/GandiV5/Data/ClassMethods.html +223 -0
  11. data/doc/GandiV5/Data/Converter/ArrayOf.html +413 -0
  12. data/doc/GandiV5/Data/Converter/Symbol.html +322 -0
  13. data/doc/GandiV5/Data/Converter/Time.html +330 -0
  14. data/doc/GandiV5/Data/Converter.html +433 -0
  15. data/doc/GandiV5/Data.html +785 -0
  16. data/doc/GandiV5/Domain/AutoRenew.html +1237 -0
  17. data/doc/GandiV5/Domain/Availability/Product/Period.html +220 -0
  18. data/doc/GandiV5/Domain/Availability/Product/Price.html +1031 -0
  19. data/doc/GandiV5/Domain/Availability/Product.html +988 -0
  20. data/doc/GandiV5/Domain/Availability/Tax.html +440 -0
  21. data/doc/GandiV5/Domain/Availability.html +1020 -0
  22. data/doc/GandiV5/Domain/Contact.html +4459 -0
  23. data/doc/GandiV5/Domain/Contract.html +520 -0
  24. data/doc/GandiV5/Domain/Dates.html +1313 -0
  25. data/doc/GandiV5/Domain/RenewalInformation.html +1147 -0
  26. data/doc/GandiV5/Domain/RestoreInformation.html +339 -0
  27. data/doc/GandiV5/Domain/SharingSpace.html +437 -0
  28. data/doc/GandiV5/Domain/TLD.html +1565 -0
  29. data/doc/GandiV5/Domain.html +16847 -0
  30. data/doc/GandiV5/Email/Mailbox/Responder.html +1560 -0
  31. data/doc/GandiV5/Email/Mailbox.html +6307 -0
  32. data/doc/GandiV5/Email/Offer.html +514 -0
  33. data/doc/GandiV5/Email/Slot.html +4244 -0
  34. data/doc/GandiV5/Email.html +144 -0
  35. data/doc/GandiV5/Error/GandiError.html +270 -0
  36. data/doc/GandiV5/Error.html +151 -0
  37. data/doc/GandiV5/LiveDNS/Domain.html +2984 -0
  38. data/doc/GandiV5/LiveDNS/RecordSet.html +1593 -0
  39. data/doc/GandiV5/LiveDNS/Zone/Snapshot.html +1556 -0
  40. data/doc/GandiV5/LiveDNS/Zone.html +8891 -0
  41. data/doc/GandiV5/LiveDNS.html +300 -0
  42. data/doc/GandiV5/Organization.html +2341 -0
  43. data/doc/GandiV5.html +1183 -0
  44. data/doc/_index.html +474 -0
  45. data/doc/class_list.html +51 -0
  46. data/doc/css/common.css +1 -0
  47. data/doc/css/full_list.css +58 -0
  48. data/doc/css/style.css +496 -0
  49. data/doc/file.README.html +175 -0
  50. data/doc/file_list.html +56 -0
  51. data/doc/frames.html +17 -0
  52. data/doc/index.html +175 -0
  53. data/doc/js/app.js +303 -0
  54. data/doc/js/full_list.js +216 -0
  55. data/doc/js/jquery.js +4 -0
  56. data/doc/method_list.html +2427 -0
  57. data/doc/top-level-namespace.html +110 -0
  58. data/gandi_v5.gemspec +1 -1
  59. data/lib/gandi_v5/billing.rb +2 -2
  60. data/lib/gandi_v5/data.rb +2 -0
  61. data/lib/gandi_v5/domain/auto_renew.rb +4 -4
  62. data/lib/gandi_v5/domain/availability/product/period.rb +24 -0
  63. data/lib/gandi_v5/domain/availability/product/price.rb +36 -0
  64. data/lib/gandi_v5/domain/availability/product.rb +52 -0
  65. data/lib/gandi_v5/domain/availability/tax.rb +20 -0
  66. data/lib/gandi_v5/domain/availability.rb +49 -0
  67. data/lib/gandi_v5/domain/tld.rb +57 -0
  68. data/lib/gandi_v5/domain.rb +41 -86
  69. data/lib/gandi_v5/email/mailbox/responder.rb +43 -2
  70. data/lib/gandi_v5/email/mailbox.rb +32 -21
  71. data/lib/gandi_v5/email/offer.rb +2 -2
  72. data/lib/gandi_v5/email/slot.rb +42 -16
  73. data/lib/gandi_v5/error/gandi_error.rb +2 -2
  74. data/lib/gandi_v5/live_dns/domain.rb +59 -45
  75. data/lib/gandi_v5/live_dns/zone/snapshot.rb +27 -8
  76. data/lib/gandi_v5/live_dns/zone.rb +63 -59
  77. data/lib/gandi_v5/live_dns.rb +20 -0
  78. data/lib/gandi_v5/organization.rb +2 -2
  79. data/lib/gandi_v5/version.rb +1 -1
  80. data/lib/gandi_v5.rb +25 -5
  81. data/spec/features/domain_spec.rb +1 -1
  82. data/spec/fixtures/bodies/{GandiV5_Domain/availability.yaml → GandiV5_Domain_Availability/fetch.yaml} +0 -0
  83. data/spec/fixtures/bodies/{GandiV5_Domain/tld.yaml → GandiV5_Domain_TLD/fetch.yaml} +0 -0
  84. data/spec/fixtures/bodies/{GandiV5_Domain/tlds.yaml → GandiV5_Domain_TLD/list.yaml} +0 -0
  85. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/{get.yaml → fetch.yaml} +0 -0
  86. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/list.yaml +3 -0
  87. data/spec/units/gandi_v5/billing_spec.rb +2 -2
  88. data/spec/units/gandi_v5/domain/auto_renew_spec.rb +5 -5
  89. data/spec/units/gandi_v5/domain/availability/product/period_spec.rb +4 -0
  90. data/spec/units/gandi_v5/domain/availability/product/price_spec.rb +4 -0
  91. data/spec/units/gandi_v5/domain/availability/product_spec.rb +4 -0
  92. data/spec/units/gandi_v5/domain/availability/tax_spec.rb +4 -0
  93. data/spec/units/gandi_v5/domain/availability_spec.rb +43 -0
  94. data/spec/units/gandi_v5/domain/tld_spec.rb +29 -0
  95. data/spec/units/gandi_v5/domain_spec.rb +89 -81
  96. data/spec/units/gandi_v5/email/mailbox/responder_spec.rb +52 -0
  97. data/spec/units/gandi_v5/email/mailbox_spec.rb +56 -27
  98. data/spec/units/gandi_v5/email/offer_spec.rb +1 -1
  99. data/spec/units/gandi_v5/email/slot_spec.rb +101 -13
  100. data/spec/units/gandi_v5/live_dns/domain_spec.rb +70 -40
  101. data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +32 -3
  102. data/spec/units/gandi_v5/live_dns/zone_spec.rb +68 -50
  103. data/spec/units/gandi_v5/live_dns_spec.rb +24 -0
  104. data/spec/units/gandi_v5/organization_spec.rb +1 -1
  105. data/spec/units/gandi_v5_spec.rb +37 -12
  106. metadata +72 -9
  107. data/TODO.md +0 -29
@@ -0,0 +1,110 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Top Level Namespace
8
+
9
+ &mdash; Documentation by YARD 0.9.19
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ pathId = "";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+
41
+
42
+ <span class="title">Top Level Namespace</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Top Level Namespace
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+ </div>
80
+
81
+ <h2>Defined Under Namespace</h2>
82
+ <p class="children">
83
+
84
+
85
+
86
+
87
+ <strong class="classes">Classes:</strong> <span class='object_link'><a href="GandiV5.html" title="GandiV5 (class)">GandiV5</a></span>
88
+
89
+
90
+ </p>
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+ </div>
101
+
102
+ <div id="footer">
103
+ Generated on Mon Jul 22 16:44:23 2019 by
104
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
+ 0.9.19 (ruby-2.6.3).
106
+ </div>
107
+
108
+ </div>
109
+ </body>
110
+ </html>
data/gandi_v5.gemspec CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |gem|
32
32
  gem.add_development_dependency 'rb-inotify', '~> 0.9'
33
33
  gem.add_development_dependency 'rspec', '>= 3.7', '< 4'
34
34
  gem.add_development_dependency 'rspec-its', '~> 1.3'
35
- gem.add_development_dependency 'rubocop', '~> 0.67'
35
+ gem.add_development_dependency 'rubocop', '~> 0.73'
36
36
  gem.add_development_dependency 'rubocop-performance', '~> 1.1'
37
37
  gem.add_development_dependency 'simplecov', '~> 0.7'
38
38
  gem.add_development_dependency 'timecop', '~> 0.5'
@@ -11,9 +11,9 @@ class GandiV5
11
11
  # @param url [sharing_id] the Sharing ID of the organisation to get info for
12
12
  # defaults to the user the api key belomgs to.
13
13
  # @return [GandiV5::Billing::Info]
14
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
14
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
15
15
  def self.info(sharing_id = nil)
16
- data = GandiV5.get url(sharing_id)
16
+ _response, data = GandiV5.get url(sharing_id)
17
17
  GandiV5::Billing::Info.from_gandi data
18
18
  end
19
19
 
data/lib/gandi_v5/data.rb CHANGED
@@ -181,7 +181,9 @@ class GandiV5
181
181
  define_method "#{name}=" do |value|
182
182
  instance_variable_set("@#{name}", value)
183
183
  end
184
+ # rubocop:disable Style/AccessModifierDeclarations
184
185
  private "#{name}="
186
+ # rubocop:enable Style/AccessModifierDeclarations
185
187
  end
186
188
 
187
189
  # @api private
@@ -21,10 +21,10 @@ class GandiV5
21
21
 
22
22
  # Disable auto renewal for the associated domain.
23
23
  # @return [String] The confirmation message from Gandi.
24
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
24
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
25
25
  def disable
26
26
  body = { enabled: false }.to_json
27
- data = GandiV5.patch url, body
27
+ _response, data = GandiV5.patch url, body
28
28
  self.enabled = false
29
29
  data['message']
30
30
  end
@@ -35,7 +35,7 @@ class GandiV5
35
35
  # @return [String] The confirmation message from Gandi.
36
36
  # @raise [ArgumentError] if duration is invalid (not 1 to 9 (inclusive)).
37
37
  # @raise [ArgumentError] if org_id is not passed and not set for this domain.
38
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
38
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
39
39
  def enable(duration: self.duration || 1, org_id: self.org_id)
40
40
  fail ArgumentError, 'duration can not be less than 1' if duration < 1
41
41
  fail ArgumentError, 'duration can not be more than 9' if duration > 9
@@ -47,7 +47,7 @@ class GandiV5
47
47
  org_id: org_id
48
48
  }.to_json
49
49
 
50
- data = GandiV5.patch url, body
50
+ _response, data = GandiV5.patch url, body
51
51
  self.enabled = true
52
52
  self.duration = duration
53
53
  self.org_id = org_id
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class Domain
5
+ class Availability
6
+ class Product
7
+ # Information about an available product.
8
+ # @!attribute [r] name
9
+ # @return [String]
10
+ # @!attribute [r]
11
+ # @return [Time] starts_at
12
+ # @!attribute [r]
13
+ # @return [Time, nil] ends_at
14
+ class Period
15
+ include GandiV5::Data
16
+
17
+ members :name
18
+ member :starts_at, converter: GandiV5::Data::Converter::Time
19
+ member :ends_at, converter: GandiV5::Data::Converter::Time
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class Domain
5
+ class Availability
6
+ class Product
7
+ # Information about an available product.
8
+ # @!attribute [r] duration_unit
9
+ # @return [String] time unit for the duration (e.g. y)
10
+ # @!attribute [r] max_duration
11
+ # @return [Integer] maximum duration for which this price unit applies
12
+ # @!attribute [r] min_duration
13
+ # @return [Integer] minimum duration for which this price unit applies.
14
+ # @!attribute [r] price_after_taxes
15
+ # @return [Numeric] pricing after tax is applied
16
+ # @!attribute [r] price_before_taxes
17
+ # @return [Numeric] pricing before tax is applied
18
+ # @!attribute [r] discount
19
+ # @return [Boolean, nil] whether a discount is active on this price unit
20
+ # @!attribute [r] normal_price_after_taxes
21
+ # @return [Numeric, nil] pricing after tax is applied, when no discount applies
22
+ # @!attribute [r] normal_price_before_taxes
23
+ # @return [Numeric, nil] pricing before tax is applied, when no discount applies
24
+ # @!attribute [r] type
25
+ # @return [String, nil]
26
+ class Price
27
+ include GandiV5::Data
28
+
29
+ members :duration_unit, :max_duration, :min_duration,
30
+ :price_after_taxes, :price_before_taxes,
31
+ :discount, :normal_price_after_taxes, :normal_price_after_taxes, :type
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'product/price'
4
+ require_relative 'product/period'
5
+
6
+ class GandiV5
7
+ class Domain
8
+ class Availability
9
+ # Information about an available product.
10
+ # @!attribute [r] name
11
+ # @return [String]
12
+ # @!attribute [r] prices
13
+ # @return [Array<GandiV5::Domain::Availability::Product::Price>]
14
+ # @!attribute [r] periods
15
+ # @return [Array<GandiV5::Domain::Availability::Product::Period>]
16
+ # @!attribute [r] taxes
17
+ # @return [Array<GandiV5::Domain::Availability::Tax>]
18
+ # @!attribute [r] process
19
+ # @return [Symbol]
20
+ # @!attribute [r] status
21
+ # @return [Symbol]
22
+ class Product
23
+ include GandiV5::Data
24
+
25
+ STATUSES = {
26
+ available: 'Domain name is available',
27
+ available_reserved: 'Domain name reserved under special conditions',
28
+ available_preorder: 'Domain name can be pre-ordered',
29
+ unavailable: 'Domain name is not available',
30
+ unavailable_premium: 'Domain name is not available',
31
+ unavailable_restricted: 'Domain name is not available (forbidden)',
32
+ error_invalid: 'Provided value is not a valid domain name',
33
+ error_refused: 'Service is temporarily down',
34
+ error_timeout: 'Service timed out, try the method again later',
35
+ error_unknown: 'Internal server error',
36
+ reserved_corporate: 'The TLD for the given domain name is reserved for ' \
37
+ 'Gandi Corporate Services customers',
38
+ pending: 'Result is not yet ready, try the method again later',
39
+ error_eoi: 'The TLD for the given domain name is in an ' \
40
+ 'Expression of Interest (EOI) period'
41
+ }.freeze
42
+
43
+ members :name
44
+ member :prices, converter: GandiV5::Domain::Availability::Product::Price, array: true
45
+ member :periods, converter: GandiV5::Domain::Availability::Product::Period, array: true
46
+ member :process, converter: GandiV5::Data::Converter::Symbol
47
+ member :status, converter: GandiV5::Data::Converter::Symbol
48
+ member :taxes, converter: GandiV5::Domain::Availability::Tax, array: true
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class Domain
5
+ class Availability
6
+ # Information about tax due on a process/product.
7
+ # @!attribute [r] name
8
+ # @return [String] name of the tax (e.g. VAT)
9
+ # @!attribute [r] rate
10
+ # @return [Numeric] percentage rate of the tax (e.g. 20)
11
+ # @!attribute [r] type
12
+ # @return [String] type of the tax (e.g. service)
13
+ class Tax
14
+ include GandiV5::Data
15
+
16
+ members :name, :rate, :type
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'availability/tax'
4
+ require_relative 'availability/product'
5
+
6
+ class GandiV5
7
+ class Domain
8
+ # Information about the availabillity of processes on a domain.
9
+ # @!attribute [r] currency
10
+ # @return [String]
11
+ # @!attribute [r] grid
12
+ # @return [String]
13
+ # @!attribute [r] products
14
+ # @return [Arrav<GandiV5::Domain::Availability::Product>]
15
+ # @!attribute [r] taxes
16
+ # @return [Array<GandiV5::Domain::Availability::Tax>]
17
+ class Availability
18
+ include GandiV5::Data
19
+
20
+ members :currency, :grid
21
+ member :products, converter: GandiV5::Domain::Availability::Product, array: true
22
+ member :taxes, converter: GandiV5::Domain::Availability::Tax, array: true
23
+
24
+ # Check domain availability and pricing.
25
+ # @see https://api.gandi.net/docs/domains#get-v5-domain-check
26
+ # @param fqdn [String, #to_s] the fully qualified domain name to check.
27
+ # @param country [String, #to_s] (optional)
28
+ # ISO country code for which taxes are to be applied.
29
+ # @param currency [String, #to_s] (optional) request price for a specific ISO currency code.
30
+ # @param duration_unit [String, #to_s] (optional) define the unit for max_duration.
31
+ # @param extension [String, #to_s] (optional) query a specific extension for product options.
32
+ # @param grid [String, #to_s] (optional) request price for a specific rate.
33
+ # @param lang [String, #to_s] (optional) language code.
34
+ # @param max_duration [Integer, #to_s] (optional)
35
+ # set a limit on the duration range for returned prices.
36
+ # @param period [String, #to_s] (optional) specific registration period to query.
37
+ # @param processes [Array<:create, :renew, :transfer etc.>] (optional default [:create])
38
+ # list of at least 1 process for which pricing is to be made.
39
+ # @param sharing_id [String, #to_s] (optional)
40
+ # organization for which the pricing is to be made.
41
+ # @return [GandiV5::Domain::Availability]
42
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
43
+ def self.fetch(fqdn, **options)
44
+ _response, data = GandiV5.get("#{BASE}domain/check", params: { name: fqdn }.merge(options))
45
+ GandiV5::Domain::Availability.from_gandi data
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class Domain
5
+ # Information about a specific TLD (Top Level Domain).
6
+ # @!attribute [r] name
7
+ # @return [String]
8
+ # @!attribute [r] full_tld
9
+ # @return [String]
10
+ # @!attribute [r] authinfo_for_transfer
11
+ # @return [Boolean] whether authinfo is required for a transfer.
12
+ # @!attribute [r] category
13
+ # @return [String]
14
+ # @!attribute [r] change_owner
15
+ # @return [Boolean] whther changing owner is pemritted.
16
+ # @!attribute [r] corporate
17
+ # @return [Boolean] whether this is a corporate TLD.
18
+ # @!attribute [r] ext_trade
19
+ # @return [Boolean]
20
+ # @!attribute [r] lock
21
+ # @return [Boolean]
22
+ class TLD
23
+ include GandiV5::Data
24
+
25
+ members :name, :full_tld, :authinfo_for_transfer, :change_owner, :corporate, :ext_trade, :lock
26
+ member :category, converter: GandiV5::Data::Converter::Symbol
27
+
28
+ # List of available TLDs.
29
+ # @see https://api.gandi.net/docs/domains#get-v5-domain-tlds
30
+ # @return Array<GandiV5::Domain::TLD>
31
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
32
+ def self.list
33
+ GandiV5.get(url)
34
+ .last
35
+ .map { |tld| GandiV5::Domain::TLD.from_gandi tld }
36
+ end
37
+
38
+ # Get TLD information.
39
+ # @see https://api.gandi.net/docs/domains#get-v5-domain-tlds-name
40
+ # @param name [String, #to_s] the top level domain to get information for.
41
+ # @return [GandiV5::Domain::TLD]
42
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
43
+ def self.fetch(name)
44
+ _response, data = GandiV5.get url(name)
45
+ GandiV5::Domain::TLD.from_gandi data
46
+ end
47
+
48
+ private
49
+
50
+ def self.url(name = nil)
51
+ "#{BASE}domain/tlds" +
52
+ (name ? "/#{CGI.escape name}" : '')
53
+ end
54
+ private_class_method :url
55
+ end
56
+ end
57
+ end
@@ -1,28 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # TODO: Add method renewal_price(currency: 'GBP', period: 1, sharing_id: self.sharing_id)
4
-
5
- # TODO: Glue Record Management
6
- # * get-v5-domain-domains-domain-hosts
7
- # * post-v5-domain-domains-domain-hosts
8
- # TODO: Glue Record Information
9
- # * get-v5-domain-domains-domain-hosts-name
10
- # * put-v5-domain-domains-domain-hosts-name
11
- # * delete-v5-domain-domains-domain-hosts-name
12
- # TODO: LiveDNS Management
13
- # * get-v5-domain-domains-domain-livedns
14
- # * post-v5-domain-domains-domain-livedns
15
- # TODO: Nameservers Management
16
- # * get-v5-domain-domains-domain-nameservers
17
- # * put-v5-domain-domains-domain-nameservers
18
-
19
3
  require_relative 'domain/auto_renew'
4
+ require_relative 'domain/availability'
20
5
  require_relative 'domain/contact'
21
6
  require_relative 'domain/contract'
22
7
  require_relative 'domain/dates'
23
8
  require_relative 'domain/renewal_information'
24
9
  require_relative 'domain/restore_information'
25
10
  require_relative 'domain/sharing_space'
11
+ require_relative 'domain/tld'
26
12
 
27
13
  class GandiV5
28
14
  # Gandi Domain Management API.
@@ -175,7 +161,7 @@ class GandiV5
175
161
  # Contacts for the domain.
176
162
  # @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-contacts
177
163
  # @return [Hash{:owner, :admin, :bill, :tech => GandiV5::Domain::Contact}]
178
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
164
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
179
165
  def contacts
180
166
  @contacts ||= fetch_contacts
181
167
  end
@@ -183,9 +169,9 @@ class GandiV5
183
169
  # Requery Gandi for the domain's contacts.
184
170
  # @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-contacts
185
171
  # @return [Hash{:owner, :admin, :bill, :tech => GandiV5::Domain::Contact}]
186
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
172
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
187
173
  def fetch_contacts
188
- data = GandiV5.get url('contacts')
174
+ _response, data = GandiV5.get url('contacts')
189
175
  self.contacts = data.transform_keys(&:to_sym)
190
176
  CONTACTS_CONVERTER.call contacts
191
177
  end
@@ -199,7 +185,7 @@ class GandiV5
199
185
  # @param tech [GandiV5::Domain::Contact, #to_gandi, #to_h]
200
186
  # details for the new technical contact.
201
187
  # @return [Hash{:owner, :admin, :bill, :tech => GandiV5::Domain::Contact}]
202
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
188
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
203
189
  def update_contacts(admin: nil, bill: nil, tech: nil)
204
190
  body = {
205
191
  admin: admin.respond_to?(:to_gandi) ? admin.to_gandi : admin,
@@ -214,7 +200,7 @@ class GandiV5
214
200
  # Renewal information for the domain.
215
201
  # @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-renew
216
202
  # @return [GandiV5::Domain::RenewalInformation]
217
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
203
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
218
204
  def renewal_information
219
205
  @renewal_information ||= fetch_renewal_information
220
206
  end
@@ -222,9 +208,9 @@ class GandiV5
222
208
  # Requery Gandi for the domain's renewal information.
223
209
  # @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-renew
224
210
  # @return [GandiV5::Domain::RenewalInformation]
225
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
211
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
226
212
  def fetch_renewal_information
227
- data = GandiV5.get url('renew')
213
+ _response, data = GandiV5.get url('renew')
228
214
  data = data['renew'].merge('contracts' => data['contracts'])
229
215
  @renewal_information = GandiV5::Domain::RenewalInformation.from_gandi data
230
216
  end
@@ -234,31 +220,29 @@ class GandiV5
234
220
  # @see https://api.gandi.net/docs/domains#post-v5-domain-domains-domain-renew
235
221
  # @param duration [Integer, #to_s] how long to renew for (in years).
236
222
  # @return [String] confirmation message from Gandi.
237
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
223
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
238
224
  def renew_for(duration = 1)
239
225
  body = { duration: duration }.to_json
240
- data = GandiV5.post url('renew'), body
226
+ _response, data = GandiV5.post url('renew'), body
241
227
  data['message']
242
228
  end
243
229
 
244
- # TODO: Test when I have a restorable domain
245
230
  # Restoration information for the domain.
246
231
  # @see https://docs.gandi.net/en/domain_names/renew/restore.html
247
232
  # @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-restore
248
233
  # @return [GandiV5::Domain::RestoreInformation]
249
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
234
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
250
235
  def restore_information
251
236
  @restore_information ||= fetch_restore_information
252
237
  end
253
238
 
254
- # TODO: Test when I have a restorable domain
255
239
  # Requery Gandi for the domain's restore information.
256
240
  # @see https://docs.gandi.net/en/domain_names/renew/restore.html
257
241
  # @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain-restore
258
242
  # @return [GandiV5::Domain::RestoreInformation]
259
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
243
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
260
244
  def fetch_restore_information
261
- data = GandiV5.get url('restore')
245
+ _response, data = GandiV5.get url('restore')
262
246
  @restore_information = GandiV5::Domain::RestoreInformation.from_gandi data
263
247
  rescue RestClient::NotFound
264
248
  @restore_information = GandiV5::Domain::RestoreInformation.from_gandi restorable: false
@@ -269,21 +253,33 @@ class GandiV5
269
253
  # @see https://docs.gandi.net/en/domain_names/renew/restore.html
270
254
  # @see https://api.gandi.net/docs/domains#post-v5-domain-domains-domain-restore
271
255
  # @return [String] The confirmation message from Gandi.
272
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
256
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
273
257
  def restore
274
- data = GandiV5.post url('restore'), '{}'
258
+ _response, data = GandiV5.post url('restore'), '{}'
275
259
  data['message']
276
260
  end
277
261
 
278
262
  # Requery Gandi fo this domain's information.
279
263
  # @return [GandiV5::Domain]
280
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
264
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
281
265
  def refresh
282
- data = GandiV5.get url
266
+ _response, data = GandiV5.get url
283
267
  from_gandi data
284
268
  auto_renew.domain = self
285
269
  end
286
270
 
271
+ # Get the price for renewing this domain.
272
+ # @param currency [String] the currency to get the price in (e.g. GBP)
273
+ # @param period [Integer] the number of year(s) renewal to get the price for
274
+ # @return [GandiV5::Domain::Availability::Product::Price]
275
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error
276
+ def renewal_price(currency: 'GBP', period: 1)
277
+ arguments = { processes: [:renew], currency: currency, period: period }
278
+ GandiV5::Domain::Availability.fetch(fqdn, **arguments)
279
+ .products.first
280
+ .prices.first
281
+ end
282
+
287
283
  # Create (register) a new domain.
288
284
  # Warning! This is not a free operation. Please ensure your prepaid account has enough credit.
289
285
  # @see https://api.gandi.net/docs/domains#post-v5-domain-domains
@@ -319,27 +315,28 @@ class GandiV5
319
315
  # "eap7", "eap8", "eap9", "golive", #to_gandi, #to_json] (optional)
320
316
  # @see https://docs.gandi.net/en/domain_names/register/new_gtld.html
321
317
  # @param dry_run [Boolean] whether the details should be checked
322
- # instead of actually creating the domain.
323
- # @return [Hash] if actually creating, you get what Gandi returns.
324
- # @return [Hash] if doing a dry run, you get what Gandi returns.
325
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
326
- # TODO: Return created domain unless dry_run
318
+ # instead of actually creating the domain
319
+ # @return [GandiV5::Domain] the created domain
320
+ # @return [Hash] if doing a dry run, you get what Gandi returns
321
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error
327
322
  def self.create(fqdn, dry_run: false, **params)
328
323
  fail ArgumentError, 'missing keyword: owner' unless params.key?(:owner)
329
324
 
330
325
  body = params.merge(fqdn: fqdn)
331
326
  .transform_values { |val| val.respond_to?(:to_gandi) ? val.to_gandi : val }
332
327
  .to_json
333
- GandiV5.post url, body, 'Dry-Run': dry_run ? 1 : 0
328
+
329
+ response, data = GandiV5.post(url, body, 'Dry-Run': dry_run ? 1 : 0)
330
+ dry_run ? data : fetch(response.headers[:location].split('/').last)
334
331
  end
335
332
 
336
333
  # Get information on a domain.
337
334
  # @see https://api.gandi.net/docs/domains#get-v5-domain-domains-domain
338
335
  # @param fqdn [String, #to_s] the fully qualified domain name to fetch.
339
336
  # @return [GandiV5::Domain]
340
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
337
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
341
338
  def self.fetch(fqdn)
342
- data = GandiV5.get url(fqdn)
339
+ _response, data = GandiV5.get url(fqdn)
343
340
  domain = from_gandi data
344
341
  domain.auto_renew.domain = fqdn
345
342
  domain
@@ -357,13 +354,13 @@ class GandiV5
357
354
  # @param sort_by [String, #to_s] (optional default "fqdn") how to sort the list.
358
355
  # @param tld [String, #to_s] (optional) used to filter by just the top level domain.
359
356
  # @return [Array<GandiV5::Domain>]
360
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
357
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
361
358
  def self.list(page: (1..), per_page: 100, **params)
362
359
  page = [page.to_i] unless page.respond_to?(:each)
363
360
 
364
361
  domains = []
365
362
  page.each do |page_number|
366
- data = GandiV5.get url, params: params.merge(page: page_number, per_page: per_page)
363
+ _resp, data = GandiV5.get url, params: params.merge(page: page_number, per_page: per_page)
367
364
  break if data.empty?
368
365
 
369
366
  domains += data.map { |domain| from_gandi domain }
@@ -372,48 +369,6 @@ class GandiV5
372
369
  domains
373
370
  end
374
371
 
375
- # Check domain availability and pricing.
376
- # @see https://api.gandi.net/docs/domains#get-v5-domain-check
377
- # @param fqdn [String, #to_s] the fully qualified domain name to check.
378
- # @param country [String, #to_s] (optional) ISO country code for which taxes are to be applied.
379
- # @param currency [String, #to_s] (optional) request price for a specific ISO currency code.
380
- # @param duration_unit [String, #to_s] (optional) define the unit for max_duration.
381
- # @param extension [String, #to_s] (optional) query a specific extension for product options.
382
- # @param grid [String, #to_s] (optional) request price for a specific rate.
383
- # @param lang [String, #to_s] (optional) language code.
384
- # @param max_duration [Integer, #to_s] (optional)
385
- # set a limit on the duration range for returned prices.
386
- # @param period [String, #to_s] (optional) specific registration period to query.
387
- # @param _ [Array<:create, :renew, :transfer etc.>] (optional default [:create])
388
- # list of at least 1 process for which pricing is to be made.
389
- # @param sharing_id [String, #to_s] (optional) organization for which the pricing is to be made.
390
- # @return [Hash]
391
- # TODO: Return an Availabillity object ???
392
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
393
- def self.availability(fqdn, **options)
394
- GandiV5.get "#{BASE}domain/check", params: { name: fqdn }.merge(options)
395
- end
396
-
397
- # List of available TLDs.
398
- # @see https://api.gandi.net/docs/domains#get-v5-domain-tlds
399
- # @return Array<String>
400
- # TODO: Maybe return an array of TLD objects ???
401
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
402
- def self.tlds
403
- GandiV5.get("#{BASE}domain/tlds")
404
- .map { |hash| hash['name'] }
405
- end
406
-
407
- # Get TLD information.
408
- # @see https://api.gandi.net/docs/domains#get-v5-domain-tlds-name
409
- # @param name [String, #to_s] the top level domain to get information for.
410
- # @return [Hash]
411
- # TODO: Return a TLD object ???
412
- # @raise [GandiV5::Error::GandiError::GandiError] if Gandi returns an error.
413
- def self.tld(name)
414
- GandiV5.get("#{BASE}domain/tlds/#{CGI.escape name}").transform_keys(&:to_sym)
415
- end
416
-
417
372
  private
418
373
 
419
374
  def url(extra = nil)