gandi_v5 0.9.1 → 0.10.0

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