ovh-provisioner 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.gitlab-ci.yml +23 -0
  4. data/.rspec +2 -0
  5. data/.ruby-version +1 -0
  6. data/CHANGELOG +7 -0
  7. data/CONTRIBUTING.md +62 -0
  8. data/Gemfile +6 -0
  9. data/LICENSE +202 -0
  10. data/README.md +107 -0
  11. data/Rakefile +24 -0
  12. data/bin/console +32 -0
  13. data/bin/ovh_provisioner +27 -0
  14. data/bin/setup +23 -0
  15. data/lib/ovh/provisioner.rb +43 -0
  16. data/lib/ovh/provisioner/api_list.rb +158 -0
  17. data/lib/ovh/provisioner/api_object/api_object.rb +125 -0
  18. data/lib/ovh/provisioner/api_object/dedicated_server.rb +225 -0
  19. data/lib/ovh/provisioner/api_object/domain_zone.rb +115 -0
  20. data/lib/ovh/provisioner/api_object/ip.rb +83 -0
  21. data/lib/ovh/provisioner/api_object/record.rb +48 -0
  22. data/lib/ovh/provisioner/api_object/vrack.rb +92 -0
  23. data/lib/ovh/provisioner/cli.rb +173 -0
  24. data/lib/ovh/provisioner/cli_domain.rb +138 -0
  25. data/lib/ovh/provisioner/cli_ip.rb +64 -0
  26. data/lib/ovh/provisioner/cli_vrack.rb +71 -0
  27. data/lib/ovh/provisioner/init.rb +77 -0
  28. data/lib/ovh/provisioner/self_cli.rb +81 -0
  29. data/lib/ovh/provisioner/spawner.rb +63 -0
  30. data/lib/ovh/provisioner/version.rb +24 -0
  31. data/ovh-provisioner.gemspec +53 -0
  32. data/spec/config.yml +53 -0
  33. data/spec/helpers/highline_helper.rb +36 -0
  34. data/spec/ovh/provisioner/cli_domain_spec.rb +140 -0
  35. data/spec/ovh/provisioner/cli_ip_spec.rb +90 -0
  36. data/spec/ovh/provisioner/cli_spec.rb +186 -0
  37. data/spec/ovh/provisioner/cli_vrack_spec.rb +83 -0
  38. data/spec/ovh/provisioner/stubs/domain_stubs.rb +204 -0
  39. data/spec/ovh/provisioner/stubs/ip_stubs.rb +152 -0
  40. data/spec/ovh/provisioner/stubs/server_stubs.rb +146 -0
  41. data/spec/ovh/provisioner/stubs/vrack_stubs.rb +87 -0
  42. data/spec/ovh/provisioner_spec.rb +25 -0
  43. data/spec/spec_helper.rb +47 -0
  44. metadata +350 -0
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module OVH
20
+ # Define version
21
+ module Provisioner
22
+ VERSION = '0.1.0'
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ lib = File.expand_path('lib', __dir__)
20
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
21
+ require 'ovh/provisioner/version'
22
+
23
+ Gem::Specification.new do |spec|
24
+ spec.name = 'ovh-provisioner'
25
+ spec.version = OVH::Provisioner::VERSION
26
+ spec.authors = ['Samuel Bernard']
27
+ spec.email = ['samuel.bernard@gmail.com']
28
+ spec.license = 'Apache-2.0'
29
+
30
+ spec.summary = 'Provision dedicated servers hosted by OVH'
31
+ spec.description = IO.read(File.join(File.dirname(__FILE__), 'README.md'))
32
+ spec.homepage = 'https://gitlab.com/sre-gems/ovh-provisioner'
33
+
34
+ spec.files = `git ls-files`.lines.map(&:chomp)
35
+ spec.bindir = 'bin'
36
+ spec.executables = `git ls-files bin/*`.lines.map do |exe|
37
+ File.basename(exe.chomp)
38
+ end
39
+ spec.require_paths = ['lib']
40
+
41
+ spec.add_development_dependency 'bundler', '~> 1.10'
42
+ spec.add_development_dependency 'rake', '~> 12'
43
+ spec.add_development_dependency 'rspec', '~> 3'
44
+ spec.add_development_dependency 'rubocop', '~> 0.40'
45
+ spec.add_development_dependency 'webmock', '~> 3'
46
+
47
+ spec.add_dependency 'celluloid', '~> 0.17'
48
+ spec.add_dependency 'hashdiff', '~> 0.3'
49
+ spec.add_dependency 'highline', '~> 2.0'
50
+ spec.add_dependency 'ovh-rest', '~> 0.0.5'
51
+ spec.add_dependency 'ruby-progressbar', '~> 1.10'
52
+ spec.add_dependency 'thor', '~> 0.19'
53
+ end
@@ -0,0 +1,53 @@
1
+ api_url: https://api.test.com/1.0
2
+ app_key: TestAppKey
3
+ app_secret: TestAppSecret
4
+ consumer_key: ConsumerKey
5
+ template: test-template
6
+ use_distrib_kernel: true
7
+ ssh_key_name: testKey
8
+
9
+ name_scheme: "[dc]-[flavor_tag]-[id].[vrack.name].test.com"
10
+
11
+ flavors:
12
+ compute_2016:
13
+ tag: comp16
14
+ hardware:
15
+ memorySize:
16
+ unit: MB
17
+ value: 131072
18
+ diskGroups:
19
+ - numberOfDisks: 2
20
+ diskType: SSD
21
+ diskSize:
22
+ unit: GB
23
+ value: 480
24
+ raidController: MegaRaid 9271-4i
25
+ processorName: E5-2640v3
26
+ description: Serveur Infrastructure HG 1U (max 4 disques)
27
+ numberOfProcessors: 2
28
+ coresPerProcessor: 8
29
+ usbKeys: null
30
+ storage_2016:
31
+ tag: sto16
32
+ hardware:
33
+ memorySize:
34
+ unit: MB
35
+ value: 262144
36
+ diskGroups:
37
+ - numberOfDisks: 2
38
+ diskType: SSD
39
+ diskSize:
40
+ unit: GB
41
+ value: 480
42
+ raidController: MegaRaid 9271-4i
43
+ - numberOfDisks: 10
44
+ diskType: SAS
45
+ diskSize:
46
+ unit: GB
47
+ value: 6000
48
+ raidController: MegaRaid 9271-4i
49
+ processorName: E5-2660v3
50
+ description: Serveur Infrastructure BIG-HG 2U (max 12 disques)
51
+ numberOfProcessors: 2
52
+ coresPerProcessor: 10
53
+ usbKeys: null
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'highline/import'
20
+
21
+ shared_context :highline, :highline do
22
+ let(:io_in) { StringIO.new }
23
+ let(:io_out) { StringIO.new }
24
+ before { HighLine.default_instance = HighLine.new(io_in, io_out) }
25
+
26
+ def provide_input(text)
27
+ io_in << "#{text}\n"
28
+ io_in.rewind
29
+ end
30
+
31
+ def consume_output
32
+ text = io_out.string.dup
33
+ io_out.truncate(io_out.rewind)
34
+ text
35
+ end
36
+ end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+
21
+ # rubocop:disable Metrics/BlockLength
22
+ subcommand = 'domain'
23
+ describe "ovh-provisioner #{subcommand}", :highline do
24
+ context 'list' do
25
+ it 'should output the list of domains' do
26
+ out = <<-OUTPUT.gsub(/^ /, '')
27
+ domain_zone:
28
+ afirsttest.com, dnssec enabled, 6 records
29
+ anothertest.com, dnssec disabled, 2 records
30
+ sotested.net, dnssec not supported, 0 records
31
+ OUTPUT
32
+ expect { start(self, subcommand) }.to output(out).to_stdout
33
+ end
34
+ end
35
+
36
+ context 'show test.com' do
37
+ it 'should output \'afirsttest.com\' details (with records) ' do
38
+ out = <<-OUTPUT.gsub(/^ /, '')
39
+ afirsttest.com - dnssec: enabled
40
+ A:
41
+ foo 1 A 1.2.4.5
42
+ some.sub 2 A 7.7.7.7
43
+ test-server-01 2 A 1.1.1.1
44
+ CNAME:
45
+ sub.www 2 CNAME some.cname.com.
46
+ test-undef-3 0 CNAME test-server-03
47
+ NS:
48
+ afirsttest.com. 0 NS somedns.ovh.net
49
+ anothertest.com - dnssec: disabled
50
+ MX:
51
+ anothertest.com. 3 MX redirect.something.net
52
+ SRV:
53
+ _imaps._tcp 0 SRV 0 0 993 ssl.something.net
54
+ OUTPUT
55
+ expect { start(self, subcommand) }.to output(out).to_stdout
56
+ end
57
+ end
58
+
59
+ context 'show test.org' do
60
+ it 'should exit with error because no domains match test.org' do
61
+ out = <<-OUTPUT.gsub(/^ /, '')
62
+ No registered services of your account match test.org
63
+ OUTPUT
64
+ expect { start(self, subcommand) }.to output(out).to_stdout
65
+ end
66
+ end
67
+
68
+ context 'add firsttest -d test -y cname -t serv.dom.io.' do
69
+ it 'should add record \'test 0 CNAME serv.dom.io.\' to afirsttest.com' do
70
+ ask = <<-OUTPUT.gsub(/^ /, '')
71
+ You are going to add a record to afirsttest.com:
72
+ test 0 CNAME serv.dom.io.
73
+ Do you want to proceed?
74
+ OUTPUT
75
+ out = <<-OUTPUT.gsub(/^ /, '')
76
+ afirsttest.com, add record:
77
+ test 0 CNAME serv.dom.io.
78
+ OUTPUT
79
+ provide_input('yes')
80
+ expect { start(self, subcommand) }.to output(out).to_stdout
81
+ expect(consume_output).to eq(ask)
82
+ end
83
+ end
84
+
85
+ context 'add firsttest -d test -y A -t serv.dom.io.' do
86
+ it 'should fail because target (serv.dom.io.) is not a valid IPv4' do
87
+ ask = <<-OUTPUT.gsub(/^ /, '')
88
+ You are going to add a record to afirsttest.com:
89
+ test 0 A serv.dom.io.
90
+ Do you want to proceed?
91
+ OUTPUT
92
+ out = <<-OUTPUT.gsub(/^ /, '')
93
+ Invalid IPv4 serv.dom.io. for A record of test.afirsttest.com
94
+ OUTPUT
95
+ provide_input('yes')
96
+ expect { start(self, subcommand) }.to output(out).to_stdout
97
+ expect(consume_output).to eq(ask)
98
+ end
99
+ end
100
+
101
+ context 'add test.com -d test -y cname -t serv.dom.io.' do
102
+ it 'should exit with error because two domains match test.com' do
103
+ out = <<-OUTPUT.gsub(/^ /, '')
104
+ Need one zone, got many: ["afirsttest.com", "anothertest.com"]
105
+ OUTPUT
106
+ expect { start(self, subcommand) }.to output(out).to_stdout
107
+ end
108
+ end
109
+
110
+ context 'rm afirsttest -d sub -l 2' do
111
+ it 'should ask to remove two records and do it' do
112
+ ask = <<-OUTPUT.gsub(/^ /, '')
113
+ You are going to remove theses zones from afirsttest.com:
114
+ A:
115
+ some.sub 2 A 7.7.7.7
116
+ CNAME:
117
+ sub.www 2 CNAME some.cname.com.
118
+ Do you want to proceed?
119
+ OUTPUT
120
+ out = <<-OUTPUT.gsub(/^ /, '')
121
+ afirsttest.com, remove records:
122
+ some.sub 2 A 7.7.7.7
123
+ sub.www 2 CNAME some.cname.com.
124
+ OUTPUT
125
+ provide_input('yes')
126
+ expect { start(self, subcommand) }.to output(out).to_stdout
127
+ expect(consume_output).to eq(ask)
128
+ end
129
+ end
130
+
131
+ context 'rm afirsttest -t notarget' do
132
+ it 'should do nothing because no records match target condition' do
133
+ out = <<-OUTPUT.gsub(/^ /, '')
134
+ Nothing to do…
135
+ OUTPUT
136
+ expect { start(self, subcommand) }.to output(out).to_stdout
137
+ end
138
+ end
139
+ end
140
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+
21
+ # rubocop:disable Metrics/BlockLength
22
+ describe 'ovh-provisioner ip', :highline do
23
+ context 'list' do
24
+ it 'should output the list of IPs' do
25
+ out = <<-OUTPUT.gsub(/^ /, '')
26
+ ip:
27
+ test-server-01:
28
+ ipv4:
29
+ 1.1.1.1/32 - test-server-01(dedicated) - non endable
30
+ reverse: test-server-01.test.com.
31
+ description: First server
32
+ test-server-02:
33
+ ipv4:
34
+ 2.2.2.2/32 - test-server-02(dedicated) - endable
35
+ test-server-03:
36
+ ipv4:
37
+ 3.3.3.3/32 - test-server-03(dedicated) - non endable
38
+ organisation_id: test
39
+ country: some
40
+ OUTPUT
41
+ expect { start(self, 'ip') }.to output(out).to_stdout
42
+ end
43
+ end
44
+
45
+ context 'set_reverse 2.2 test-server-02.test.com' do
46
+ it 'should ask then set 2.2.2.2 reverse to test-server-02.test.com' do
47
+ ask = <<-OUTPUT.gsub(/^ /, '')
48
+ You are going to set the reverse of 2.2.2.2/32 to test-server-02.test.com
49
+ Do you want to proceed?
50
+ OUTPUT
51
+ out = <<-OUTPUT.gsub(/^ /, '')
52
+ 2.2.2.2/32 - reverse test-server-02.test.com has been added
53
+ OUTPUT
54
+ provide_input('yes')
55
+ expect { start(self, 'ip') }.to output(out).to_stdout
56
+ expect(consume_output).to eq(ask)
57
+ end
58
+ end
59
+
60
+ context 'set_reverse 3.3 invalid-test-03' do
61
+ it 'should ask then failed to set 3.3.3.3 reverse to invalid-test-03' do
62
+ ask = <<-OUTPUT.gsub(/^ /, '')
63
+ You are going to set the reverse of 3.3.3.3/32 to invalid-test-03
64
+ Do you want to proceed?
65
+ OUTPUT
66
+ out = <<-OUTPUT.gsub(/^ /, '')
67
+ Cannot check if invalid-test-03. resolves to 3.3.3.3
68
+ OUTPUT
69
+ provide_input('yes')
70
+ expect { start(self, 'ip') }.to output(out).to_stdout
71
+ expect(consume_output).to eq(ask)
72
+ end
73
+ end
74
+
75
+ context 'rm_reverse 1.1.1.1' do
76
+ it 'should ask then remove 1.1.1.1 reverse' do
77
+ ask = <<-OUTPUT.gsub(/^ /, '')
78
+ You are going to remove the reverse of 1.1.1.1/32
79
+ Do you want to proceed?
80
+ OUTPUT
81
+ out = <<-OUTPUT.gsub(/^ /, '')
82
+ 1.1.1.1/32 - reverse test-server-01.test.com. has been removed
83
+ OUTPUT
84
+ provide_input('yes')
85
+ expect { start(self, 'ip') }.to output(out).to_stdout
86
+ expect(consume_output).to eq(ask)
87
+ end
88
+ end
89
+ end
90
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+ # rubocop:disable Metrics/BlockLength
21
+ describe 'ovh-provisioner', :highline do
22
+ context 'version' do
23
+ it 'should output the correct version' do
24
+ out = "OVH Provisioner version #{OVH::Provisioner::VERSION}\n"
25
+ expect { start(self) }.to output(out).to_stdout
26
+ end
27
+ end
28
+
29
+ context 'list' do
30
+ it 'should output the list of dedicated servers' do
31
+ out = <<-OUTPUT.gsub(/^ /, '')
32
+ dedicated_server:
33
+ avrack:
34
+ compute_2016:
35
+ test-server-01.afirsttest.com[test-server-01/1]
36
+ test - compute_2016 - avrack:1.1.1.1 - harddisk:centos7_64 - ok
37
+ Setting things up
38
+ bvrack:
39
+ storage_2016:
40
+ test-server-02.afirsttest.com[test-server-02/2]
41
+ test - storage_2016 - bvrack:2.2.2.2 - rescue:centos7_64 - ok
42
+ Rebooting
43
+ none:
44
+ undefined:
45
+ test-server-03.afirsttest.com[test-server-03/3]
46
+ test - undefined - none:3.3.3.3 - pxe:centos7_64 - ok
47
+ Server is not being installed or reinstalled at the moment
48
+ OUTPUT
49
+ expect { start(self) }.to output(out).to_stdout
50
+ end
51
+ end
52
+
53
+ context 'install 03' do
54
+ it 'should ask but then refuse to reinstall test-server-03' do
55
+ ask = <<-OUTPUT.gsub(/^ /, '')
56
+ You are going to (re)install those servers:
57
+ dedicated_server:
58
+ Server is not being installed or reinstalled at the moment:
59
+ undefined:
60
+ test-server-03.afirsttest.com[test-server-03/3]
61
+ test - undefined - none:3.3.3.3 - pxe:centos7_64 - ok
62
+ Server is not being installed or reinstalled at the moment
63
+ Do you want to proceed?
64
+ OUTPUT
65
+ out = <<-OUTPUT.gsub(/^ /, '')
66
+ test-server-03: failed
67
+ An OS is already installed (centos7_64) but option force is false
68
+ OUTPUT
69
+ provide_input('yes')
70
+ expect { start(self) }.to output(out).to_stdout
71
+ expect(consume_output).to eq(ask)
72
+ end
73
+ end
74
+
75
+ context 'install --force 03' do
76
+ it 'should reinstall test-server-03 with distrib kernel' do
77
+ out = <<-OUTPUT.gsub(/^ /, '')
78
+ test-server-03: ok
79
+ Installation of test-template launched
80
+ OUTPUT
81
+ provide_input('yes')
82
+ expect { start(self) }.to output(out).to_stdout
83
+ url = 'https://api.test.com/1.0/dedicated/server/test-server-03'
84
+ body = {
85
+ 'templateName' => 'test-template',
86
+ 'details' => {
87
+ 'customHostname' => 'test-server-03.afirsttest.com',
88
+ 'useDistribKernel' => true,
89
+ 'sshKeyName' => 'testKey'
90
+ }
91
+ }
92
+ expect(a_request(:post, "#{url}/install/start").with(body: body))
93
+ .to have_been_made.times(1)
94
+ end
95
+ end
96
+
97
+ context 'install --no-use-distrib-kernel --force 03' do
98
+ it 'should reinstall test-server-03 with ovh kernel' do
99
+ out = <<-OUTPUT.gsub(/^ /, '')
100
+ test-server-03: ok
101
+ Installation of test-template launched
102
+ OUTPUT
103
+ provide_input('yes')
104
+ expect { start(self) }.to output(out).to_stdout
105
+ url = 'https://api.test.com/1.0/dedicated/server/test-server-03'
106
+ body = {
107
+ 'templateName' => 'test-template',
108
+ 'details' => {
109
+ 'customHostname' => 'test-server-03.afirsttest.com',
110
+ 'useDistribKernel' => false,
111
+ 'sshKeyName' => 'testKey'
112
+ }
113
+ }
114
+ expect(a_request(:post, "#{url}/install/start").with(body: body))
115
+ .to have_been_made.times(1)
116
+ end
117
+ end
118
+
119
+ name_scheme = '%<location>s-%<flavor_tag>s-%<server_id>s'
120
+ context "rename 01 02 -n #{name_scheme} -d afirsttest.com" do
121
+ it 'should ask then rename test-server-0[1, 2] while removing old names' do
122
+ ask = <<-OUTPUT.gsub(/^ /, '')
123
+ You are going to rename those servers:
124
+ test-server-01.afirsttest.com => test-comp16-1.afirsttest.com
125
+ test-server-02.afirsttest.com => test-sto16-2.afirsttest.com
126
+ Do you want to proceed?
127
+ OUTPUT
128
+ out = <<-OUTPUT.gsub(/^ /, '')
129
+ afirsttest.com, add record:
130
+ test-comp16-1 0 A 1.1.1.1
131
+ test-sto16-2 0 A 2.2.2.2
132
+ To complete renaming, call "set_reverse" in a few minute
133
+ OUTPUT
134
+ provide_input('yes')
135
+ expect { start(self) }.to output(out).to_stdout
136
+ expect(consume_output).to eq(ask)
137
+ url = 'https://api.test.com/1.0/domain/zone'
138
+ expect(a_request(:delete, "#{url}/afirsttest.com/record/9"))
139
+ .to have_been_made.times(1)
140
+ end
141
+ end
142
+
143
+ context "rename 03 -n #{name_scheme} -d afirsttest.com" do
144
+ it 'should ask but failed to rename test-server-03 (name already used)' do
145
+ ask = <<-OUTPUT.gsub(/^ /, '')
146
+ You are going to rename those servers:
147
+ test-server-03.afirsttest.com => test-undef-3.afirsttest.com
148
+ Do you want to proceed?
149
+ OUTPUT
150
+ out = <<-OUTPUT.gsub(/^ /, '')
151
+ test-server-03.afirsttest.com: name already used
152
+ To complete renaming, call "set_reverse" in a few minute
153
+ OUTPUT
154
+ provide_input('yes')
155
+ expect { start(self) }.to output(out).to_stdout
156
+ expect(consume_output).to eq(ask)
157
+ end
158
+ end
159
+
160
+ context "set_reverse 01 02 -n #{name_scheme} -d afirsttest.com" do
161
+ it 'should fail to set_reverse test-server-0[1, 2] (does not resolve)' do
162
+ out = <<-OUTPUT.gsub(/^ /, '')
163
+ test-server-01.afirsttest.com: DNS propagation is not finished, try later_
164
+ test-server-02.afirsttest.com: DNS propagation is not finished, try later_
165
+ OUTPUT
166
+ expect { start(self) }.to output(out).to_stdout
167
+ end
168
+ end
169
+
170
+ context "set_reverse 03 -n #{name_scheme} -d afirsttest.com" do
171
+ it 'should set the reverse of test-server-03 in two tries' do
172
+ out1 = <<-OUTPUT.gsub(/^ /, '')
173
+ test-server-03.afirsttest.com: DNS propagation is not finished, try later_
174
+ OUTPUT
175
+ out2 = <<-OUTPUT.gsub(/^ /, '')
176
+ 3.3.3.3/32 - reverse test-undef-3.afirsttest.com has been added
177
+ OUTPUT
178
+ expect { start(self) }.to output(out1).to_stdout
179
+ expect { start(self) }.to output(out2).to_stdout
180
+ url = 'https://api.test.com/1.0/ip'
181
+ expect(a_request(:post, "#{url}/3.3.3.3%2F32/reverse"))
182
+ .to have_been_made.times(2)
183
+ end
184
+ end
185
+ end
186
+ # rubocop:enable Metrics/BlockLength