hybrid_platforms_conductor 32.16.3 → 33.0.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/README.md +6 -3
  4. data/bin/last_deploys +4 -1
  5. data/bin/nodes_to_deploy +5 -5
  6. data/docs/config_dsl.md +45 -1
  7. data/docs/executables.md +6 -7
  8. data/docs/executables/check-node.md +3 -3
  9. data/docs/executables/deploy.md +3 -3
  10. data/docs/executables/dump_nodes_json.md +3 -3
  11. data/docs/executables/test.md +3 -3
  12. data/docs/executables/topograph.md +3 -3
  13. data/docs/gen/mermaid/README.md-0.png +0 -0
  14. data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
  15. data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
  16. data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
  17. data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
  18. data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
  19. data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
  20. data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
  21. data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
  22. data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
  23. data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
  24. data/docs/plugins.md +47 -0
  25. data/docs/plugins/connector/ssh.md +1 -1
  26. data/docs/plugins/log/remote_fs.md +26 -0
  27. data/docs/plugins/secrets_reader/cli.md +31 -0
  28. data/docs/plugins/secrets_reader/thycotic.md +46 -0
  29. data/docs/plugins/test/bitbucket_conf.md +1 -1
  30. data/docs/plugins/test/check_deploy_and_idempotence.md +1 -1
  31. data/docs/plugins/test/connection.md +1 -0
  32. data/docs/plugins/test/deploy_removes_root_access.md +1 -1
  33. data/docs/plugins/test/file_system.md +1 -0
  34. data/docs/plugins/test/github_ci.md +48 -0
  35. data/docs/plugins/test/hostname.md +1 -0
  36. data/docs/plugins/test/ip.md +1 -0
  37. data/docs/plugins/test/jenkins_ci_conf.md +1 -1
  38. data/docs/plugins/test/jenkins_ci_masters_ok.md +1 -1
  39. data/docs/plugins/test/local_users.md +1 -0
  40. data/docs/plugins/test/mounts.md +1 -0
  41. data/docs/plugins/test/orphan_files.md +1 -0
  42. data/docs/plugins/test/ports.md +1 -0
  43. data/docs/plugins/test/spectre.md +1 -0
  44. data/docs/plugins/test/vulnerabilities.md +1 -0
  45. data/lib/hybrid_platforms_conductor/actions_executor.rb +8 -1
  46. data/lib/hybrid_platforms_conductor/common_config_dsl/github.rb +62 -0
  47. data/lib/hybrid_platforms_conductor/deployer.rb +193 -141
  48. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +3 -3
  49. data/lib/hybrid_platforms_conductor/hpc_plugins/log/my_log_plugin.rb.sample +100 -0
  50. data/lib/hybrid_platforms_conductor/hpc_plugins/log/remote_fs.rb +179 -0
  51. data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/cli.rb +75 -0
  52. data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/my_secrets_reader_plugin.rb.sample +46 -0
  53. data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/thycotic.rb +87 -0
  54. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +1 -1
  55. data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +3 -1
  56. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +7 -20
  57. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +1 -1
  58. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +2 -1
  59. data/lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb +32 -0
  60. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +3 -1
  61. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +3 -1
  62. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +3 -1
  63. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +3 -1
  64. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +3 -1
  65. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +3 -1
  66. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +3 -1
  67. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +2 -1
  68. data/lib/hybrid_platforms_conductor/log.rb +31 -0
  69. data/lib/hybrid_platforms_conductor/plugins.rb +1 -0
  70. data/lib/hybrid_platforms_conductor/secrets_reader.rb +31 -0
  71. data/lib/hybrid_platforms_conductor/test_only_remote_node.rb +18 -0
  72. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  73. data/spec/hybrid_platforms_conductor_test.rb +27 -6
  74. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +3 -3
  75. data/spec/hybrid_platforms_conductor_test/api/deployer/config_dsl_spec.rb +46 -4
  76. data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +187 -212
  77. data/spec/hybrid_platforms_conductor_test/api/deployer/log_plugins/remote_fs_spec.rb +223 -0
  78. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +4 -4
  79. data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/cli_spec.rb +63 -0
  80. data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/thycotic_spec.rb +253 -0
  81. data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +1 -1
  82. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb +72 -0
  83. data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +146 -98
  84. data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +240 -83
  85. data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +2 -1
  86. data/spec/hybrid_platforms_conductor_test/executables/options/deployer_spec.rb +0 -182
  87. data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +1 -1
  88. data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +40 -53
  89. data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +251 -15
  90. data/spec/hybrid_platforms_conductor_test/test_log_no_read_plugin.rb +82 -0
  91. data/spec/hybrid_platforms_conductor_test/test_log_plugin.rb +103 -0
  92. data/spec/hybrid_platforms_conductor_test/test_secrets_reader_plugin.rb +45 -0
  93. metadata +41 -2
@@ -4,238 +4,213 @@ describe HybridPlatformsConductor::Deployer do
4
4
 
5
5
  deploy_specs_for(check_mode: false)
6
6
 
7
- # Expect the test services handler to be called to deploy a given list of services
8
- #
9
- # Parameters::
10
- # * *services* (Hash<String, Array<String> >): List of services to be expected, per node name
11
- def expect_services_handler_to_deploy(services)
12
- expect(test_services_handler).to receive(:deploy_allowed?).with(
13
- services: services,
14
- secrets: {},
15
- local_environment: false
16
- ) do
17
- nil
18
- end
19
- expect(test_services_handler).to receive(:package).with(
20
- services: services,
21
- secrets: {},
22
- local_environment: false
23
- )
24
- expect(test_services_handler).to receive(:prepare_for_deploy).with(
25
- services: services,
26
- secrets: {},
27
- local_environment: false,
28
- why_run: false
29
- )
30
- services.each do |node, services|
31
- expect(test_services_handler).to receive(:actions_to_deploy_on).with(node, services, false) do
32
- [{ bash: "echo \"Deploying on #{node}\"" }]
7
+ context 'checking log plugins usage' do
8
+
9
+ # Prepare the test platform with test log plugins
10
+ #
11
+ # Parameters::
12
+ # * *platforms_info* (Hash): The platforms info [default = {}]
13
+ # * *as_git* (Boolean): As a git repository? [default = false]
14
+ # * *additional_config* (String): Additional config [default = 'send_logs_to :test_log']
15
+ def with_test_platform_for_deploy_tests(platforms_info = {}, as_git = false, additional_config = 'send_logs_to :test_log')
16
+ with_test_platform(platforms_info, false, additional_config) do
17
+ yield
33
18
  end
34
- expect(test_services_handler).to receive(:log_info_for).with(node, services) do
35
- {
36
- repo_name_0: 'platform',
37
- commit_id_0: '123456',
38
- commit_message_0: "Test commit for #{node}: #{services.join(', ')}"
39
- }
19
+ end
20
+
21
+ it 'deploys correct logs information on 1 node' do
22
+ with_test_platform_for_deploy_tests({ nodes: { 'node' => { services: %w[service1 service2] } } }, true) do
23
+ with_connections_mocked_on ['node'] do
24
+ test_actions_executor.connector(:ssh).ssh_user = 'test_user'
25
+ expect_services_handler_to_deploy('node' => %w[service1 service2])
26
+ expect_actions_executor_runs([
27
+ # First run, we expect the mutex to be setup, and the deployment actions to be run
28
+ proc { |actions_per_nodes| expect_actions_to_deploy_on(actions_per_nodes, 'node') },
29
+ # Second run, we expect the mutex to be released
30
+ proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, 'node') },
31
+ # Third run, we expect logs to be uploaded on the node
32
+ proc { |actions_per_nodes| expect(actions_per_nodes).to eq('node' => [{ bash: 'echo Save test logs to node' }]) }
33
+ ])
34
+ expect(test_deployer.deploy_on('node')).to eq('node' => [0, 'Deploy successful', ''])
35
+ expect(HybridPlatformsConductorTest::TestLogPlugin.calls).to eq [
36
+ {
37
+ method: :actions_to_save_logs,
38
+ node: 'node',
39
+ services: %w[service1 service2],
40
+ deployment_info: {
41
+ repo_name_0: 'platform',
42
+ commit_id_0: '123456',
43
+ commit_message_0: 'Test commit for node: service1, service2',
44
+ user: 'test_user'
45
+ },
46
+ exit_status: 0,
47
+ stdout: 'Deploy successful',
48
+ stderr: ''
49
+ }
50
+ ]
51
+ end
40
52
  end
41
53
  end
42
- end
43
54
 
44
- it 'deploys correct logs information on 1 node' do
45
- with_test_platform({ nodes: { 'node' => { services: %w[service1 service2] } } }, true) do
46
- with_connections_mocked_on ['node'] do
47
- test_actions_executor.connector(:ssh).ssh_user = 'test_user'
48
- expect_services_handler_to_deploy('node' => %w[service1 service2])
49
- expect_actions_executor_runs([
50
- # First run, we expect the mutex to be setup, and the deployment actions to be run
51
- proc { |actions_per_nodes| expect_actions_to_deploy_on(actions_per_nodes, 'node') },
52
- # Second run, we expect the mutex to be released
53
- proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, 'node') },
54
- # Third run, we expect logs to be uploaded on the node
55
- proc do |actions_per_nodes|
56
- # Check logs content
57
- local_log_file = actions_per_nodes['node'][:scp].first[0]
58
- expect(File.exist?(local_log_file)).to eq true
59
- expect_logs_to_be(File.read(local_log_file), 'Deploy successful', '',
60
- date: /\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/,
61
- user: 'test_user',
62
- debug: 'No',
63
- repo_name_0: 'platform',
64
- commit_id_0: '123456',
65
- commit_message_0: 'Test commit for node: service1, service2',
66
- services: 'service1, service2',
67
- exit_status: '0'
68
- )
69
- expect_actions_to_upload_logs(actions_per_nodes, 'node')
70
- end
71
- ])
72
- expect(test_deployer.deploy_on('node')).to eq('node' => [0, 'Deploy successful', ''])
55
+ it 'deploys correct logs information on several nodes' do
56
+ with_test_platform_for_deploy_tests({ nodes: {
57
+ 'node1' => { services: %w[service1] },
58
+ 'node2' => { services: %w[service2] }
59
+ } }, true) do
60
+ with_connections_mocked_on %w[node1 node2] do
61
+ test_actions_executor.connector(:ssh).ssh_user = 'test_user'
62
+ expect_services_handler_to_deploy(
63
+ 'node1' => %w[service1],
64
+ 'node2' => %w[service2]
65
+ )
66
+ expect_actions_executor_runs([
67
+ # First run, we expect the mutex to be setup, and the deployment actions to be run
68
+ proc { |actions_per_nodes| expect_actions_to_deploy_on(actions_per_nodes, %w[node1 node2]) },
69
+ # Second run, we expect the mutex to be released
70
+ proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, %w[node1 node2]) },
71
+ # Third run, we expect logs to be uploaded on the node
72
+ proc do |actions_per_nodes|
73
+ expect(actions_per_nodes).to eq(
74
+ 'node1' => [{ bash: 'echo Save test logs to node1' }],
75
+ 'node2' => [{ bash: 'echo Save test logs to node2' }]
76
+ )
77
+ end
78
+ ])
79
+ expect(test_deployer.deploy_on(%w[node1 node2])).to eq(
80
+ 'node1' => [0, 'Deploy successful', ''],
81
+ 'node2' => [0, 'Deploy successful', '']
82
+ )
83
+ expect(HybridPlatformsConductorTest::TestLogPlugin.calls).to eq [
84
+ {
85
+ method: :actions_to_save_logs,
86
+ node: 'node1',
87
+ services: %w[service1],
88
+ deployment_info: {
89
+ repo_name_0: 'platform',
90
+ commit_id_0: '123456',
91
+ commit_message_0: 'Test commit for node1: service1',
92
+ user: 'test_user'
93
+ },
94
+ exit_status: 0,
95
+ stdout: 'Deploy successful',
96
+ stderr: ''
97
+ },
98
+ {
99
+ method: :actions_to_save_logs,
100
+ node: 'node2',
101
+ services: %w[service2],
102
+ deployment_info: {
103
+ repo_name_0: 'platform',
104
+ commit_id_0: '123456',
105
+ commit_message_0: 'Test commit for node2: service2',
106
+ user: 'test_user'
107
+ },
108
+ exit_status: 0,
109
+ stdout: 'Deploy successful',
110
+ stderr: ''
111
+ }
112
+ ]
113
+ end
73
114
  end
74
115
  end
75
- end
76
116
 
77
- it 'deploys correct logs information on several nodes' do
78
- with_test_platform({ nodes: {
79
- 'node1' => { services: %w[service1] },
80
- 'node2' => { services: %w[service2] }
81
- } }, true) do
82
- with_connections_mocked_on %w[node1 node2] do
83
- test_actions_executor.connector(:ssh).ssh_user = 'test_user'
84
- expect_services_handler_to_deploy(
85
- 'node1' => %w[service1],
86
- 'node2' => %w[service2]
87
- )
88
- expect_actions_executor_runs([
89
- # First run, we expect the mutex to be setup, and the deployment actions to be run
90
- proc { |actions_per_nodes| expect_actions_to_deploy_on(actions_per_nodes, %w[node1 node2]) },
91
- # Second run, we expect the mutex to be released
92
- proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, %w[node1 node2]) },
93
- # Third run, we expect logs to be uploaded on the node
94
- proc do |actions_per_nodes|
95
- # Check logs content
96
- local_log_file1 = actions_per_nodes['node1'][:scp].first[0]
97
- expect(File.exist?(local_log_file1)).to eq true
98
- expect_logs_to_be(File.read(local_log_file1), 'Deploy successful', '',
99
- date: /\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/,
100
- user: 'test_user',
101
- debug: 'No',
102
- repo_name_0: 'platform',
103
- commit_id_0: '123456',
104
- commit_message_0: 'Test commit for node1: service1',
105
- services: 'service1',
106
- exit_status: '0'
107
- )
108
- local_log_file2 = actions_per_nodes['node2'][:scp].first[0]
109
- expect(File.exist?(local_log_file2)).to eq true
110
- expect_logs_to_be(File.read(local_log_file2), 'Deploy successful', '',
111
- date: /\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/,
112
- user: 'test_user',
113
- debug: 'No',
114
- repo_name_0: 'platform',
115
- commit_id_0: '123456',
116
- commit_message_0: 'Test commit for node2: service2',
117
- services: 'service2',
118
- exit_status: '0'
119
- )
120
- expect_actions_to_upload_logs(actions_per_nodes, %w[node1 node2])
121
- end
122
- ])
123
- expect(test_deployer.deploy_on(%w[node1 node2])).to eq(
124
- 'node1' => [0, 'Deploy successful', ''],
125
- 'node2' => [0, 'Deploy successful', '']
126
- )
117
+ it 'deploys correct logs information on 1 node even when there is a failing deploy' do
118
+ with_test_platform_for_deploy_tests({ nodes: { 'node' => { services: %w[service1 service2] } } }, true) do
119
+ with_connections_mocked_on ['node'] do
120
+ test_actions_executor.connector(:ssh).ssh_user = 'test_user'
121
+ expect_services_handler_to_deploy('node' => %w[service1 service2])
122
+ expect_actions_executor_runs([
123
+ # First run, we expect the mutex to be setup, and the deployment actions to be run
124
+ proc do |actions_per_nodes|
125
+ expect_actions_to_deploy_on(
126
+ actions_per_nodes,
127
+ 'node',
128
+ mocked_result: { 'node' => [:failed_action, 'Failed deploy stdout', 'Failed deploy stderr'] }
129
+ )
130
+ end,
131
+ # Second run, we expect the mutex to be released
132
+ proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, 'node') },
133
+ # Third run, we expect logs to be uploaded on the node
134
+ proc { |actions_per_nodes| expect(actions_per_nodes).to eq('node' => [{ bash: 'echo Save test logs to node' }]) }
135
+ ])
136
+ expect(test_deployer.deploy_on('node')).to eq('node' => [:failed_action, 'Failed deploy stdout', 'Failed deploy stderr'])
137
+ expect(HybridPlatformsConductorTest::TestLogPlugin.calls).to eq [
138
+ {
139
+ method: :actions_to_save_logs,
140
+ node: 'node',
141
+ services: %w[service1 service2],
142
+ deployment_info: {
143
+ repo_name_0: 'platform',
144
+ commit_id_0: '123456',
145
+ commit_message_0: 'Test commit for node: service1, service2',
146
+ user: 'test_user'
147
+ },
148
+ exit_status: :failed_action,
149
+ stdout: 'Failed deploy stdout',
150
+ stderr: 'Failed deploy stderr'
151
+ }
152
+ ]
153
+ end
127
154
  end
128
155
  end
129
- end
130
156
 
131
- it 'deploys correct logs information on 1 node even when there is a failing deploy' do
132
- with_test_platform({ nodes: { 'node' => { services: %w[service1 service2] } } }, true) do
133
- with_connections_mocked_on ['node'] do
134
- test_actions_executor.connector(:ssh).ssh_user = 'test_user'
135
- expect_services_handler_to_deploy('node' => %w[service1 service2])
157
+ it 'gets deployment info from log plugins' do
158
+ with_test_platform_for_deploy_tests({ nodes: { 'node' => {} } }) do |repository|
136
159
  expect_actions_executor_runs([
137
- # First run, we expect the mutex to be setup, and the deployment actions to be run
160
+ # Expect the actions to get log files
138
161
  proc do |actions_per_nodes|
139
- expect_actions_to_deploy_on(
140
- actions_per_nodes,
141
- 'node',
142
- mocked_result: { 'node' => [:failed_action, "Failed deploy stdout\n", "Failed deploy stderr\n"] }
143
- )
144
- end,
145
- # Second run, we expect the mutex to be released
146
- proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, 'node') },
147
- # Third run, we expect logs to be uploaded on the node
148
- proc do |actions_per_nodes|
149
- # Check logs content
150
- local_log_file = actions_per_nodes['node'][:scp].first[0]
151
- expect(File.exist?(local_log_file)).to eq true
152
- expect_logs_to_be(File.read(local_log_file), "Failed deploy stdout\n", 'Failed deploy stderr',
153
- date: /\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/,
154
- user: 'test_user',
155
- debug: 'No',
156
- repo_name_0: 'platform',
157
- commit_id_0: '123456',
158
- commit_message_0: 'Test commit for node: service1, service2',
159
- services: 'service1, service2',
160
- exit_status: 'failed_action'
161
- )
162
- expect_actions_to_upload_logs(actions_per_nodes, 'node')
162
+ expect(actions_per_nodes).to eq('node' => [{ bash: 'echo Read logs for node' }])
163
+ { 'node' => [42, 'Log files read stdout', 'Log files read stderr'] }
163
164
  end
164
165
  ])
165
- expect(test_deployer.deploy_on('node')).to eq('node' => [:failed_action, "Failed deploy stdout\n", "Failed deploy stderr\n"])
166
+ expect(test_deployer.deployment_info_from('node')).to eq(
167
+ 'node' => {
168
+ deployment_info: { user: 'test_user' },
169
+ exit_status: 666,
170
+ services: %w[unknown],
171
+ stderr: 'Deployment test stderr',
172
+ stdout: 'Deployment test stdout'
173
+ }
174
+ )
175
+ expect(HybridPlatformsConductorTest::TestLogPlugin.calls).to eq [
176
+ {
177
+ method: :actions_to_read_logs,
178
+ node: 'node'
179
+ },
180
+ {
181
+ method: :logs_for,
182
+ node: 'node',
183
+ exit_status: 42,
184
+ stdout: 'Log files read stdout',
185
+ stderr: 'Log files read stderr'
186
+ }
187
+ ]
166
188
  end
167
189
  end
168
- end
169
-
170
- it 'gets deployment info from log files' do
171
- with_test_platform({ nodes: { 'node' => {} } }) do |repository|
172
- expect_actions_executor_runs([
173
- # Expect the actions to get log files
174
- proc do |actions_per_nodes|
175
- expect(actions_per_nodes).to eq('node' => { remote_bash: 'cd /var/log/deployments && ls -t | head -1 | xargs sed \'/===== STDOUT =====/q\'' })
176
- { 'node' => [0, "Property1: Value1\nProperty2: Value2", ''] }
177
- end
178
- ])
179
- expect(test_deployer.deployment_info_from('node')).to eq(
180
- 'node' => {
181
- Property1: 'Value1',
182
- Property2: 'Value2'
183
- }
184
- )
185
- end
186
- end
187
190
 
188
- it 'gets deployment info with some properties converted from log files' do
189
- with_test_platform({ nodes: { 'node' => {} } }) do |repository|
190
- expect_actions_executor_runs([
191
- # Expect the actions to get log files
192
- proc do |actions_per_nodes|
193
- expect(actions_per_nodes).to eq('node' => { remote_bash: 'cd /var/log/deployments && ls -t | head -1 | xargs sed \'/===== STDOUT =====/q\'' })
194
- { 'node' => [0, <<~EOS, ''] }
195
- date: Thu Nov 23 18:43:01 UTC 2017
196
- debug: Yes
197
- diff_files_0: file1, file2, file3
198
- services: service1, service2, service3
199
- EOS
200
- end
201
- ])
202
- expect(test_deployer.deployment_info_from('node')).to eq(
203
- 'node' => {
204
- date: Time.parse('2017-11-23 18:43:01 UTC'),
205
- debug: true,
206
- diff_files_0: %w[file1 file2 file3],
207
- services: %w[service1 service2 service3]
208
- }
209
- )
210
- end
211
- end
212
-
213
- it 'gets deployment info from several log files' do
214
- with_test_platform({ nodes: { 'node1' => {}, 'node2' => {} } }) do |repository|
215
- expect_actions_executor_runs([
216
- # Expect the actions to get log files
217
- proc do |actions_per_nodes|
218
- expect(actions_per_nodes).to eq(
219
- 'node1' => { remote_bash: 'cd /var/log/deployments && ls -t | head -1 | xargs sed \'/===== STDOUT =====/q\'' },
220
- 'node2' => { remote_bash: 'cd /var/log/deployments && ls -t | head -1 | xargs sed \'/===== STDOUT =====/q\'' }
221
- )
191
+ it 'gets deployment info from log plugins not having actions_to_read_logs' do
192
+ with_test_platform_for_deploy_tests({ nodes: { 'node' => {} } }, false, 'send_logs_to :test_log_no_read') do |repository|
193
+ expect(test_deployer.deployment_info_from('node')).to eq(
194
+ 'node' => {
195
+ deployment_info: { user: 'test_user' },
196
+ exit_status: 666,
197
+ services: %w[unknown],
198
+ stderr: 'Deployment test stderr',
199
+ stdout: 'Deployment test stdout'
200
+ }
201
+ )
202
+ expect(HybridPlatformsConductorTest::TestLogNoReadPlugin.calls).to eq [
222
203
  {
223
- 'node1' => [0, "Property1: Value1\nProperty2: Value2", ''],
224
- 'node2' => [0, "Property3: Value3\nProperty4: Value4", '']
204
+ method: :logs_for,
205
+ node: 'node',
206
+ exit_status: nil,
207
+ stdout: nil,
208
+ stderr: nil
225
209
  }
226
- end
227
- ])
228
- expect(test_deployer.deployment_info_from(%w[node1 node2])).to eq(
229
- 'node1' => {
230
- Property1: 'Value1',
231
- Property2: 'Value2'
232
- },
233
- 'node2' => {
234
- Property3: 'Value3',
235
- Property4: 'Value4'
236
- }
237
- )
210
+ ]
211
+ end
238
212
  end
213
+
239
214
  end
240
215
 
241
216
  end
@@ -0,0 +1,223 @@
1
+ describe HybridPlatformsConductor::Deployer do
2
+
3
+ context 'checking log plugins' do
4
+
5
+ context 'remote_fs' do
6
+
7
+ # Return a test platform ready to test the remote_fs log plugin
8
+ #
9
+ # Parameters::
10
+ # * Proc: Code called with platform prepared
11
+ def with_test_platform_for_remote_fs
12
+ with_test_platform({ nodes: { 'node' => { services: %w[service1 service2] } } }, false, 'send_logs_to :remote_fs') do
13
+ yield
14
+ end
15
+ end
16
+
17
+ it 'returns actions to save logs' do
18
+ with_test_platform_for_remote_fs do
19
+ with_connections_mocked_on ['node'] do
20
+ test_actions_executor.connector(:ssh).ssh_user = 'test_user'
21
+ expect_services_handler_to_deploy('node' => %w[service1 service2])
22
+ expect_actions_executor_runs([
23
+ # First run, we expect the mutex to be setup, and the deployment actions to be run
24
+ proc do |actions_per_nodes|
25
+ expect_actions_to_deploy_on(
26
+ actions_per_nodes,
27
+ 'node',
28
+ mocked_result: { 'node' => [0, 'Deploy successful stdout', 'Deploy successful stderr'] }
29
+ )
30
+ end,
31
+ # Second run, we expect the mutex to be released
32
+ proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, 'node') },
33
+ # Third run, we expect logs to be uploaded on the node
34
+ proc do |actions_per_nodes|
35
+ expect(actions_per_nodes['node'].size).to eq 3
36
+ expect(actions_per_nodes['node'][0].keys.sort).to eq %i[ruby remote_bash].sort
37
+ expect(actions_per_nodes['node'][0][:remote_bash]).to eq 'sudo -u root mkdir -p /var/log/deployments && sudo -u root chmod 600 /var/log/deployments'
38
+ expect(actions_per_nodes['node'][1].keys.sort).to eq %i[scp].sort
39
+ expect(actions_per_nodes['node'][1][:scp].delete(:sudo)).to eq true
40
+ expect(actions_per_nodes['node'][1][:scp].delete(:owner)).to eq 'root'
41
+ expect(actions_per_nodes['node'][1][:scp].delete(:group)).to eq 'root'
42
+ expect(actions_per_nodes['node'][1][:scp].size).to eq 1
43
+ tmp_log_file = actions_per_nodes['node'][1][:scp].first[0]
44
+ expect(actions_per_nodes['node'][1][:scp].first[1]).to eq '/var/log/deployments'
45
+ expect(actions_per_nodes['node'][2].keys.sort).to eq %i[ruby remote_bash].sort
46
+ expect(actions_per_nodes['node'][2][:remote_bash]).to eq "sudo -u root chmod 600 /var/log/deployments/#{File.basename(tmp_log_file)}"
47
+ # Call the Ruby codes to be tested
48
+ actions_per_nodes['node'][0][:ruby].call
49
+ expect(File.exist?(tmp_log_file)).to eq true
50
+ file_content_regexp = Regexp.new <<~EOREGEXP
51
+ repo_name_0: platform
52
+ commit_id_0: 123456
53
+ commit_message_0: Test commit for node: service1, service2
54
+ date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}
55
+ user: test_user
56
+ debug: No
57
+ services: service1, service2
58
+ exit_status: 0
59
+ ===== STDOUT =====
60
+ Deploy successful stdout
61
+ ===== STDERR =====
62
+ Deploy successful stderr
63
+ EOREGEXP
64
+ actions_per_nodes['node'][2][:ruby].call
65
+ # Check temporary log file gets deleted for security reasons
66
+ expect(File.exist?(tmp_log_file)).to eq false
67
+ end
68
+ ])
69
+ expect(test_deployer.deploy_on('node')).to eq('node' => [0, 'Deploy successful stdout', 'Deploy successful stderr'])
70
+ end
71
+ end
72
+ end
73
+
74
+ it 'returns actions to save logs using root' do
75
+ with_test_platform_for_remote_fs do
76
+ with_connections_mocked_on ['node'] do
77
+ test_actions_executor.connector(:ssh).ssh_user = 'root'
78
+ expect_services_handler_to_deploy('node' => %w[service1 service2])
79
+ expect_actions_executor_runs([
80
+ # First run, we expect the mutex to be setup, and the deployment actions to be run
81
+ proc do |actions_per_nodes|
82
+ expect_actions_to_deploy_on(
83
+ actions_per_nodes,
84
+ 'node',
85
+ sudo: nil,
86
+ mocked_result: { 'node' => [0, 'Deploy successful stdout', 'Deploy successful stderr'] }
87
+ )
88
+ end,
89
+ # Second run, we expect the mutex to be released
90
+ proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, 'node', sudo: nil) },
91
+ # Third run, we expect logs to be uploaded on the node
92
+ proc do |actions_per_nodes|
93
+ expect(actions_per_nodes['node'].size).to eq 3
94
+ expect(actions_per_nodes['node'][0].keys.sort).to eq %i[ruby remote_bash].sort
95
+ expect(actions_per_nodes['node'][0][:remote_bash]).to eq 'mkdir -p /var/log/deployments && chmod 600 /var/log/deployments'
96
+ expect(actions_per_nodes['node'][1].keys.sort).to eq %i[scp].sort
97
+ expect(actions_per_nodes['node'][1][:scp].delete(:sudo)).to eq false
98
+ expect(actions_per_nodes['node'][1][:scp].delete(:owner)).to eq 'root'
99
+ expect(actions_per_nodes['node'][1][:scp].delete(:group)).to eq 'root'
100
+ expect(actions_per_nodes['node'][1][:scp].size).to eq 1
101
+ tmp_log_file = actions_per_nodes['node'][1][:scp].first[0]
102
+ expect(actions_per_nodes['node'][1][:scp].first[1]).to eq '/var/log/deployments'
103
+ expect(actions_per_nodes['node'][2].keys.sort).to eq %i[ruby remote_bash].sort
104
+ expect(actions_per_nodes['node'][2][:remote_bash]).to eq "chmod 600 /var/log/deployments/#{File.basename(tmp_log_file)}"
105
+ # Call the Ruby codes to be tested
106
+ actions_per_nodes['node'][0][:ruby].call
107
+ expect(File.exist?(tmp_log_file)).to eq true
108
+ file_content_regexp = Regexp.new <<~EOREGEXP
109
+ repo_name_0: platform
110
+ commit_id_0: 123456
111
+ commit_message_0: Test commit for node: service1, service2
112
+ date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}
113
+ user: root
114
+ debug: No
115
+ services: service1, service2
116
+ exit_status: 0
117
+ ===== STDOUT =====
118
+ Deploy successful stdout
119
+ ===== STDERR =====
120
+ Deploy successful stderr
121
+ EOREGEXP
122
+ actions_per_nodes['node'][2][:ruby].call
123
+ # Check temporary log file gets deleted for security reasons
124
+ expect(File.exist?(tmp_log_file)).to eq false
125
+ end
126
+ ])
127
+ expect(test_deployer.deploy_on('node')).to eq('node' => [0, 'Deploy successful stdout', 'Deploy successful stderr'])
128
+ end
129
+ end
130
+ end
131
+
132
+ it 'reads logs' do
133
+ with_test_platform_for_remote_fs do
134
+ expect_actions_executor_runs([
135
+ # Expect the actions to get log files
136
+ proc do |actions_per_nodes|
137
+ expect(actions_per_nodes).to eq('node' => [{ remote_bash: 'sudo -u root cat /var/log/deployments/`sudo -u root ls -t /var/log/deployments/ | head -1`' }])
138
+ { 'node' => [0, <<~EOS, ''] }
139
+ repo_name_0: platform
140
+ commit_id_0: 123456
141
+ commit_message_0: Test commit for node: service1, service2
142
+ diff_files_0: file1, file2, file3
143
+ date: 2017-11-23 18:43:01
144
+ user: test_user
145
+ debug: Yes
146
+ services: service1, service2, service3
147
+ exit_status: 0
148
+ ===== STDOUT =====
149
+ Deploy successful stdout
150
+ ===== STDERR =====
151
+ Deploy successful stderr
152
+ EOS
153
+ end
154
+ ])
155
+ expect(test_deployer.deployment_info_from('node')).to eq(
156
+ 'node' => {
157
+ deployment_info: {
158
+ repo_name_0: 'platform',
159
+ commit_id_0: '123456',
160
+ commit_message_0: 'Test commit for node: service1, service2',
161
+ diff_files_0: %w[file1 file2 file3],
162
+ date: Time.parse('2017-11-23 18:43:01 UTC'),
163
+ debug: true,
164
+ user: 'test_user'
165
+ },
166
+ exit_status: 0,
167
+ services: %w[service1 service2 service3],
168
+ stderr: 'Deploy successful stderr',
169
+ stdout: 'Deploy successful stdout'
170
+ }
171
+ )
172
+ end
173
+ end
174
+
175
+ it 'reads logs using root' do
176
+ with_test_platform_for_remote_fs do
177
+ test_actions_executor.connector(:ssh).ssh_user = 'root'
178
+ expect_actions_executor_runs([
179
+ # Expect the actions to get log files
180
+ proc do |actions_per_nodes|
181
+ expect(actions_per_nodes).to eq('node' => [{ remote_bash: 'cat /var/log/deployments/`ls -t /var/log/deployments/ | head -1`' }])
182
+ { 'node' => [0, <<~EOS, ''] }
183
+ repo_name_0: platform
184
+ commit_id_0: 123456
185
+ commit_message_0: Test commit for node: service1, service2
186
+ diff_files_0: file1, file2, file3
187
+ date: 2017-11-23 18:43:01
188
+ user: test_user
189
+ debug: Yes
190
+ services: service1, service2, service3
191
+ exit_status: 0
192
+ ===== STDOUT =====
193
+ Deploy successful stdout
194
+ ===== STDERR =====
195
+ Deploy successful stderr
196
+ EOS
197
+ end
198
+ ])
199
+ expect(test_deployer.deployment_info_from('node')).to eq(
200
+ 'node' => {
201
+ deployment_info: {
202
+ repo_name_0: 'platform',
203
+ commit_id_0: '123456',
204
+ commit_message_0: 'Test commit for node: service1, service2',
205
+ diff_files_0: %w[file1 file2 file3],
206
+ date: Time.parse('2017-11-23 18:43:01 UTC'),
207
+ debug: true,
208
+ user: 'test_user'
209
+ },
210
+ exit_status: 0,
211
+ services: %w[service1 service2 service3],
212
+ stderr: 'Deploy successful stderr',
213
+ stdout: 'Deploy successful stdout'
214
+ }
215
+ )
216
+ end
217
+ end
218
+
219
+ end
220
+
221
+ end
222
+
223
+ end