gandi_v5 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/README.md +10 -6
  4. data/lib/gandi_v5.rb +2 -0
  5. data/lib/gandi_v5/domain.rb +39 -1
  6. data/lib/gandi_v5/domain/transfer_in.rb +2 -0
  7. data/lib/gandi_v5/domain/web_forwarding.rb +182 -0
  8. data/lib/gandi_v5/email.rb +2 -0
  9. data/lib/gandi_v5/email/forward.rb +1 -1
  10. data/lib/gandi_v5/email/mailbox.rb +1 -1
  11. data/lib/gandi_v5/live_dns/domain/snapshot.rb +1 -1
  12. data/lib/gandi_v5/live_dns/domain/tsig_key.rb +1 -1
  13. data/lib/gandi_v5/simple_hosting/instance.rb +6 -0
  14. data/lib/gandi_v5/simple_hosting/instance/virtual_host.rb +87 -2
  15. data/lib/gandi_v5/simple_hosting/instance/virtual_host/linked_dns_zone.rb +1 -1
  16. data/lib/gandi_v5/template.rb +271 -0
  17. data/lib/gandi_v5/template/dispatch.rb +109 -0
  18. data/lib/gandi_v5/template/payload.rb +64 -0
  19. data/lib/gandi_v5/template/payload/dns_record.rb +23 -0
  20. data/lib/gandi_v5/template/payload/web_forwarding.rb +82 -0
  21. data/lib/gandi_v5/version.rb +1 -1
  22. data/spec/fixtures/bodies/GandiV5_Domain_WebForwarding/fetch.yml +9 -0
  23. data/spec/fixtures/bodies/GandiV5_Domain_WebForwarding/list.yml +9 -0
  24. data/spec/fixtures/bodies/GandiV5_Template/fetch.yml +41 -0
  25. data/spec/fixtures/bodies/GandiV5_Template/list.yml +20 -0
  26. data/spec/fixtures/bodies/GandiV5_Template_Dispatch/fetch.yml +49 -0
  27. data/spec/spec_helper.rb +8 -7
  28. data/spec/units/gandi_v5/domain/web_forwarding_spec.rb +150 -0
  29. data/spec/units/gandi_v5/domain_spec.rb +50 -0
  30. data/spec/units/gandi_v5/simple_hosting/instance/virtual_host_spec.rb +125 -0
  31. data/spec/units/gandi_v5/simple_hosting/instance_spec.rb +8 -0
  32. data/spec/units/gandi_v5/template/dispatch_spec.rb +70 -0
  33. data/spec/units/gandi_v5/template/payload/web_forwarding_spec.rb +44 -0
  34. data/spec/units/gandi_v5/template_spec.rb +341 -0
  35. data/spec/units/gandi_v5_spec.rb +1 -1
  36. metadata +73 -47
  37. data/spec/units/gandi_v5/billing/info_spec.rb +0 -4
  38. data/spec/units/gandi_v5/domain/availability/product/period_spec.rb +0 -4
  39. data/spec/units/gandi_v5/domain/availability/product/price_spec.rb +0 -4
  40. data/spec/units/gandi_v5/domain/availability/product_spec.rb +0 -4
  41. data/spec/units/gandi_v5/domain/availability/tax_spec.rb +0 -4
  42. data/spec/units/gandi_v5/domain/contract_spec.rb +0 -4
  43. data/spec/units/gandi_v5/domain/dates_spec.rb +0 -4
  44. data/spec/units/gandi_v5/domain/restore_information_spec.rb +0 -4
  45. data/spec/units/gandi_v5/error_spec.rb +0 -4
  46. data/spec/units/gandi_v5/sharing_space_spec.rb +0 -4
  47. data/spec/units/gandi_v5/simple_hosting/instance/database_spec.rb +0 -4
  48. data/spec/units/gandi_v5/simple_hosting/instance/language_spec.rb +0 -4
  49. data/spec/units/gandi_v5/simple_hosting/instance/upgrade_spec.rb +0 -4
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class Template
5
+ class Payload
6
+ # DNS Record details of a configuration template.
7
+ # @!attribute [r] name
8
+ # @return [String]
9
+ # @!attribute [r] type
10
+ # @return [String]
11
+ # @!attribute [r] values
12
+ # @return [Array<String>]
13
+ # @!attribute [r] ttl
14
+ # @return [Integer, nil] 300-2592000.
15
+ class DNSRecord
16
+ include GandiV5::Data
17
+
18
+ members :name, :type, :ttl
19
+ member :values, array: true
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GandiV5
4
+ class Template
5
+ class Payload
6
+ # Web forwarding details of a configuration template.
7
+ # @!attribute [r] type
8
+ # @return [:cloak, :http301, :http302]
9
+ # @!attribute [r] target
10
+ # @return [String]
11
+ # @!attribute [r] fqdn
12
+ # @return [String, nil]
13
+ # @!attribute [r] override
14
+ # @return [Boolean, nil]
15
+ # when you create a redirection on a domain, a DNS record is created if it does not exist.
16
+ # When the record already exists and this parameter is set to true it will
17
+ # overwrite the record. Otherwise it will trigger an error.
18
+ # @!attribute [r] protocol
19
+ # @return [:http, :https, :https_only, nil]
20
+ class WebForwarding
21
+ include GandiV5::Data
22
+
23
+ member :type, converter: GandiV5::Data::Converter::Symbol
24
+ member :target, gandi_key: 'url'
25
+ member :fqdn, gandi_key: 'host'
26
+ member :override
27
+ member(
28
+ :protocol,
29
+ converter: GandiV5::Data::Converter.new(
30
+ from_gandi: lambda { |value|
31
+ {
32
+ 'http' => :http,
33
+ 'https' => :https,
34
+ 'httpsonly' => :https_only
35
+ }.fetch(value)
36
+ }
37
+ )
38
+ )
39
+
40
+ # Check if this is an HTTP 301 (permanent) redirection.
41
+ def http301?
42
+ type == :http301
43
+ end
44
+
45
+ # Check if this is an HTTP 302 (found) redirection.
46
+ def http302?
47
+ type == :http302
48
+ end
49
+
50
+ # Check if this is an HTTP 301 (permanent) redirection.
51
+ def permanent?
52
+ type == :http301
53
+ end
54
+
55
+ # Check if this is an HTTP 302 (found) redirection.
56
+ def found?
57
+ type == :http302
58
+ end
59
+
60
+ # Check if this is a temporary redirection.
61
+ def temporary?
62
+ type == :http302
63
+ end
64
+
65
+ # Check if it's an http end point
66
+ def http?
67
+ protocol == :http || protocol == :https
68
+ end
69
+
70
+ # Check if it's an https end point
71
+ def https?
72
+ protocol == :https || protocol == :https_only
73
+ end
74
+
75
+ # Check if it's an https only
76
+ def https_only?
77
+ protocol == :https_only
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class GandiV5
4
- VERSION = '0.9.1'
4
+ VERSION = '0.10.0'
5
5
  end
@@ -0,0 +1,9 @@
1
+ ---
2
+ created_at: '2020-11-29T14:57:14Z'
3
+ updated_at: '2020-11-29T14:57:15Z'
4
+ type: http301
5
+ host: here.example.com
6
+ protocol: https
7
+ url: https://example.com/here
8
+ cert_status: '?'
9
+ cert_uuid: cert-uuid
@@ -0,0 +1,9 @@
1
+ ---
2
+ - created_at: '2020-11-29T14:57:14Z'
3
+ updated_at: '2020-11-29T14:57:15Z'
4
+ type: http301
5
+ host: here.example.com
6
+ protocol: https
7
+ url: https://example.com/here
8
+ cert_status: '?'
9
+ cert_uuid: cert-uuid
@@ -0,0 +1,41 @@
1
+ ---
2
+ description: description of template
3
+ editable: true
4
+ href: https://api.gandi.net/v5/template/templates/template-uuid
5
+ id: template-uuid
6
+ name: template name
7
+ namespaces:
8
+ - dns:record
9
+ - domain:mailboxes
10
+ - domain:nameservers
11
+ - domain:webredirs
12
+ orgname: org-name
13
+ sharing_space:
14
+ id: sharing-space-uuid
15
+ name: sharing-space-name
16
+ reseller: true
17
+ type: user
18
+ sharing_space:
19
+ id: reseller-uuid
20
+ name: reseller-name
21
+ variables: []
22
+ payload:
23
+ 'dns:records':
24
+ records:
25
+ - name: record-name
26
+ type: TXT
27
+ values: ['record-value']
28
+ ttl: 600
29
+ 'domain:mailboxes':
30
+ values:
31
+ - login: user-name
32
+ 'domain:nameservers':
33
+ addresses: ['1.1.1.1']
34
+ service: custom
35
+ 'domain:webredirs':
36
+ values:
37
+ - type: http301
38
+ url: https://example.com/here
39
+ host: here.example.com
40
+ override: true
41
+ protocol: https
@@ -0,0 +1,20 @@
1
+ ---
2
+ - description: description of template
3
+ editable: true
4
+ href: https://api.gandi.net/v5/template/templates/template-uuid
5
+ id: template-uuid
6
+ name: template name
7
+ namespaces:
8
+ - dns:record
9
+ - domain:mailboxes
10
+ - domain:nameservers
11
+ - domain:webredirs
12
+ orgname: org-name
13
+ sharing_space:
14
+ id: sharing-space-uuid
15
+ name: sharing-space-name
16
+ reseller: true
17
+ type: user
18
+ sharing_space:
19
+ id: reseller-uuid
20
+ name: reseller-name
@@ -0,0 +1,49 @@
1
+ ---
2
+ attempt: 1
3
+ created_at: '2020-11-29T14:57:14Z'
4
+ id: dispatch-uuid
5
+ sharing_id: sharing-uuid
6
+ state: 10
7
+ state_msg: state message
8
+ task_updated_at: '2020-11-29T14:57:15Z'
9
+ template_id: template-uuid
10
+ template_name: template
11
+ target:
12
+ name: domain-api-test1.net
13
+ type: domain
14
+ target_id: target-uuid
15
+ task_history:
16
+ - namespace: 'domain:nameservers'
17
+ date: '2020-11-29T16:57:47Z'
18
+ status: 20
19
+ message: ''
20
+ task_status:
21
+ 'dns:records':
22
+ status: 0
23
+ 'domain:mailboxes':
24
+ status: 10
25
+ 'domain:nameservers':
26
+ status: 20
27
+ 'domain:webredirs':
28
+ status: 30
29
+ payload:
30
+ 'dns:records':
31
+ default: false
32
+ records:
33
+ - name: record-name
34
+ type: TXT
35
+ values: ['record-value']
36
+ ttl: 600
37
+ 'domain:mailboxes':
38
+ values:
39
+ - login: user-name
40
+ 'domain:nameservers':
41
+ addresses: ['1.1.1.1']
42
+ service: custom
43
+ 'domain:webredirs':
44
+ values:
45
+ - type: http301
46
+ url: https://example.com/here
47
+ host: here.example.com
48
+ override: true
49
+ protocol: https
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dotenv'
4
- require 'coveralls'
5
4
  require 'rspec/its'
6
5
  require 'simplecov'
6
+ require 'simplecov-lcov'
7
7
  require 'timecop'
8
8
  require 'vcr'
9
9
  require 'webmock/rspec'
@@ -13,14 +13,15 @@ allow_http_connections_to = %w[localhost 127.0.0.1]
13
13
 
14
14
  Dotenv.load File.join(__dir__, 'test.env')
15
15
 
16
- SimpleCov.coverage_dir(File.join('tmp', 'coverage')) unless ENV.key?('TRAVIS')
16
+ if ENV.key?('GITHUB_ACTIONS')
17
+ SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
18
+ SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
19
+ else
20
+ SimpleCov.coverage_dir File.join('tmp', 'coverage')
21
+ end
17
22
  SimpleCov.start do
18
23
  add_filter 'spec/'
19
- end
20
-
21
- if ENV.key?('TRAVIS')
22
- Coveralls.wear!
23
- allow_http_connections_to.push 'coveralls.io'
24
+ add_filter '.github/'
24
25
  end
25
26
 
26
27
  RSpec.configure do |config|
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::WebForwarding do
4
+ subject { described_class.new fqdn: 'host.example.com' }
5
+
6
+ describe '#update' do
7
+ let(:url) { 'https://api.gandi.net/v5/domain/domains/example.com/webredirs/host.example.com' }
8
+ let(:updated_forwarding) { double GandiV5::Domain::WebForwarding }
9
+
10
+ before :each do
11
+ expect(subject).to receive(:refresh).and_return(updated_forwarding)
12
+ subject.instance_exec { @domain = 'example.com' }
13
+ end
14
+
15
+ it 'nothing' do
16
+ expect(GandiV5).to receive(:patch).with(url, '{}')
17
+ expect(subject.update).to be updated_forwarding
18
+ end
19
+
20
+ it 'target' do
21
+ expect(GandiV5).to receive(:patch).with(url, '{"url":"new"}')
22
+ expect(subject.update(target: 'new')).to be updated_forwarding
23
+ end
24
+
25
+ it 'override' do
26
+ expect(GandiV5).to receive(:patch).with(url, '{"override":false}')
27
+ expect(subject.update(override: false)).to be updated_forwarding
28
+ end
29
+
30
+ it 'protocol' do
31
+ expect(GandiV5).to receive(:patch).with(url, '{"protocol":"httpsonly"}')
32
+ expect(subject.update(protocol: :httpsonly)).to be updated_forwarding
33
+ end
34
+
35
+ it 'type' do
36
+ expect(GandiV5).to receive(:patch).with(url, '{"type":"http302"}')
37
+ expect(subject.update(type: :http302)).to be updated_forwarding
38
+ end
39
+ end
40
+
41
+ it '#delete' do
42
+ url = 'https://api.gandi.net/v5/domain/domains/example.com/webredirs/host.example.com'
43
+ expect(GandiV5).to receive(:delete).with(url).and_return([nil, { 'message' => 'Confirmation message.' }])
44
+ subject.instance_exec { @domain = 'example.com' }
45
+ expect(subject.delete).to eq 'Confirmation message.'
46
+ end
47
+
48
+ describe 'helper methods' do
49
+ context 'an HTTP 301 redirect' do
50
+ subject { described_class.new type: :http301 }
51
+ it('#permanent?') { expect(subject.permanent?).to be true }
52
+ it('#http301?') { expect(subject.http301?).to be true }
53
+ it('#temporary?') { expect(subject.temporary?).to be false }
54
+ it('#http302?') { expect(subject.http302?).to be false }
55
+ it('#found?') { expect(subject.found?).to be false }
56
+ end
57
+
58
+ context 'an HTTP 302 redirect' do
59
+ subject { described_class.new type: :http302 }
60
+ it('#permanent?') { expect(subject.permanent?).to be false }
61
+ it('#http301?') { expect(subject.http301?).to be false }
62
+ it('#temporary?') { expect(subject.temporary?).to be true }
63
+ it('#http302?') { expect(subject.http302?).to be true }
64
+ it('#found?') { expect(subject.found?).to be true }
65
+ end
66
+
67
+ context 'an http endpoint' do
68
+ subject { described_class.new protocol: :http }
69
+ it('#http?') { expect(subject.http?).to be true }
70
+ it('#https?') { expect(subject.https?).to be false }
71
+ it('#https_only?') { expect(subject.https_only?).to be false }
72
+ end
73
+
74
+ context 'an https endpoint' do
75
+ subject { described_class.new protocol: :https }
76
+ it('#http?') { expect(subject.http?).to be true }
77
+ it('#https?') { expect(subject.https?).to be true }
78
+ it('#https_only?') { expect(subject.https_only?).to be false }
79
+ end
80
+
81
+ context 'an https_only endpoint' do
82
+ subject { described_class.new protocol: :https_only }
83
+ it('#http?') { expect(subject.http?).to be false }
84
+ it('#https?') { expect(subject.https?).to be true }
85
+ it('#https_only?') { expect(subject.https_only?).to be true }
86
+ end
87
+ end
88
+
89
+ describe '.fetch' do
90
+ subject { described_class.fetch 'example.com', 'host' }
91
+
92
+ before :each do
93
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_WebForwarding', 'fetch.yml'))
94
+ url = 'https://api.gandi.net/v5/domain/domains/example.com/webredirs/host.example.com'
95
+ expect(GandiV5).to receive(:get).with(url).and_return([nil, YAML.load_file(body_fixture)])
96
+ end
97
+
98
+ its('created_at') { should eq Time.new(2020, 11, 29, 14, 57, 14) }
99
+ its('updated_at') { should eq Time.new(2020, 11, 29, 14, 57, 15) }
100
+ its('type') { should eq :http301 }
101
+ its('fqdn') { should eq 'here.example.com' }
102
+ its('protocol') { should eq :https }
103
+ its('target') { should eq 'https://example.com/here' }
104
+ its('cert_status') { should eq '?' }
105
+ its('cert_uuid') { should eq 'cert-uuid' }
106
+ end
107
+
108
+ describe '.list' do
109
+ subject { described_class.list 'example.com' }
110
+
111
+ before :each do
112
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_WebForwarding', 'list.yml'))
113
+ url = 'https://api.gandi.net/v5/domain/domains/example.com/webredirs'
114
+ expect(GandiV5).to receive(:paginated_get).with(url, (1..), 100)
115
+ .and_yield(YAML.load_file(body_fixture))
116
+ end
117
+
118
+ its('count') { should eq 1 }
119
+ its('first.created_at') { should eq Time.new(2020, 11, 29, 14, 57, 14) }
120
+ its('first.updated_at') { should eq Time.new(2020, 11, 29, 14, 57, 15) }
121
+ its('first.type') { should eq :http301 }
122
+ its('first.fqdn') { should eq 'here.example.com' }
123
+ its('first.protocol') { should eq :https }
124
+ its('first.target') { should eq 'https://example.com/here' }
125
+ its('first.cert_status') { should eq '?' }
126
+ its('first.cert_uuid') { should eq 'cert-uuid' }
127
+ end
128
+
129
+ it '.create' do
130
+ url = 'https://api.gandi.net/v5/domain/domains/example.com/webredirs'
131
+ body = '{"host":"host","protocol":"httpsonly","type":"http302","url":"example.com","override":true}'
132
+ response = double(
133
+ RestClient::Response,
134
+ headers: { location: ' https://api.gandi.net/v5/domain/domains/example.com/webredirs/host.example.com' }
135
+ )
136
+ created_forwarding = double GandiV5::Domain::WebForwarding
137
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
138
+ expect(described_class).to receive(:fetch).with('example.com', 'host').and_return(created_forwarding)
139
+
140
+ create = {
141
+ domain: 'example.com',
142
+ host: 'host',
143
+ target: 'example.com',
144
+ protocol: :https_only,
145
+ type: :http302,
146
+ override: true
147
+ }
148
+ expect(described_class.create(**create)).to be created_forwarding
149
+ end
150
+ end
@@ -208,6 +208,18 @@ describe GandiV5::Domain do
208
208
  expect(subject.email_forwards(param: :value)).to be returns
209
209
  end
210
210
 
211
+ it '.webforwardings' do
212
+ returns = double Array
213
+ expect(GandiV5::Domain::WebForwarding).to receive(:list).with('example.com', param: :value).and_return(returns)
214
+ expect(subject.web_forwardings(param: :value)).to be returns
215
+ end
216
+
217
+ it '.webforwarding' do
218
+ returns = double Array
219
+ expect(GandiV5::Domain::WebForwarding).to receive(:fetch).with('example.com', 'host').and_return(returns)
220
+ expect(subject.web_forwarding('host')).to be returns
221
+ end
222
+
211
223
  describe '#to_s' do
212
224
  it 'Has identical fqdn and fqdn_unicode' do
213
225
  domain = described_class.new fqdn: 'example.com', fqdn_unicode: 'example.com'
@@ -494,6 +506,44 @@ describe GandiV5::Domain do
494
506
  end
495
507
  end
496
508
 
509
+ describe '#transfer_lock' do
510
+ it 'Passing nothing' do
511
+ expect(GandiV5).to receive(:patch).with(
512
+ 'https://api.gandi.net/v5/domain/domains/example.com/status',
513
+ '{"clientTransferProhibited":true}'
514
+ ).and_return([nil, { 'message' => 'Confirmation message.' }])
515
+ expect(subject.transfer_lock).to eq 'Confirmation message.'
516
+ expect(subject.status).to eq 'clientTransferProhibited'
517
+ end
518
+
519
+ it 'Passing true' do
520
+ expect(GandiV5).to receive(:patch).with(
521
+ 'https://api.gandi.net/v5/domain/domains/example.com/status',
522
+ '{"clientTransferProhibited":true}'
523
+ ).and_return([nil, { 'message' => 'Confirmation message.' }])
524
+ expect(subject.transfer_lock(true)).to eq 'Confirmation message.'
525
+ expect(subject.status).to eq 'clientTransferProhibited'
526
+ end
527
+
528
+ it 'Passing false' do
529
+ expect(GandiV5).to receive(:patch).with(
530
+ 'https://api.gandi.net/v5/domain/domains/example.com/status',
531
+ '{"clientTransferProhibited":false}'
532
+ ).and_return([nil, { 'message' => 'Confirmation message.' }])
533
+ expect(subject.transfer_lock(false)).to eq 'Confirmation message.'
534
+ expect(subject.status).to be nil
535
+ end
536
+ end
537
+
538
+ it '#transfer_unlock' do
539
+ expect(GandiV5).to receive(:patch).with(
540
+ 'https://api.gandi.net/v5/domain/domains/example.com/status',
541
+ '{"clientTransferProhibited":false}'
542
+ ).and_return([nil, { 'message' => 'Confirmation message.' }])
543
+ expect(subject.transfer_unlock).to eq 'Confirmation message.'
544
+ expect(subject.status).to be nil
545
+ end
546
+
497
547
  describe '#glue_records' do
498
548
  let(:glue_records) { double Hash }
499
549