foreman_host_reports 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +545 -0
  4. data/app/controllers/api/v2/host_reports_controller.rb +98 -0
  5. data/app/controllers/concerns/foreman_host_reports/controller/parameters/host_report.rb +25 -0
  6. data/app/controllers/host_reports_controller.rb +46 -0
  7. data/app/models/concerns/foreman_host_reports/host_extensions.rb +9 -0
  8. data/app/models/concerns/foreman_host_reports/smart_proxy_extensions.rb +9 -0
  9. data/app/models/host_report.rb +85 -0
  10. data/app/models/report_keyword.rb +11 -0
  11. data/app/views/api/v2/host_reports/base.json.rabl +5 -0
  12. data/app/views/api/v2/host_reports/create.json.rabl +5 -0
  13. data/app/views/api/v2/host_reports/index.json.rabl +5 -0
  14. data/app/views/api/v2/host_reports/main.json.rabl +15 -0
  15. data/app/views/api/v2/host_reports/show.json.rabl +11 -0
  16. data/config/routes.rb +33 -0
  17. data/db/migrate/20210112183526_add_host_reports.rb +36 -0
  18. data/db/migrate/20210616133601_create_report_keywords.rb +12 -0
  19. data/lib/foreman_host_reports/engine.rb +68 -0
  20. data/lib/foreman_host_reports/version.rb +3 -0
  21. data/lib/foreman_host_reports.rb +4 -0
  22. data/lib/tasks/foreman_host_reports_tasks.rake +50 -0
  23. data/locale/Makefile +60 -0
  24. data/locale/en/foreman_host_reports.po +19 -0
  25. data/locale/foreman_host_reports.pot +19 -0
  26. data/locale/gemspec.rb +2 -0
  27. data/package.json +45 -0
  28. data/test/controllers/api/v2/host_reports_controller_test.rb +278 -0
  29. data/test/factories/foreman_host_reports_factories.rb +21 -0
  30. data/test/snapshots/foreman-web.json +918 -0
  31. data/test/test_plugin_helper.rb +11 -0
  32. data/test/unit/foreman_host_reports_test.rb +9 -0
  33. data/webpack/global_index.js +4 -0
  34. data/webpack/global_test_setup.js +11 -0
  35. data/webpack/index.js +0 -0
  36. data/webpack/src/Router/HostReports/Components/HostReportDeleteModal.js +50 -0
  37. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.js +53 -0
  38. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.scss +4 -0
  39. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/formatCellFormatter.js +6 -0
  40. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/hostReportsToShowFormatter.js +13 -0
  41. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/index.js +4 -0
  42. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/reportToShowFormatter.js +13 -0
  43. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/statusFormatter.js +9 -0
  44. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/HostReportsToShowCell.js +32 -0
  45. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/ReportToShowCell.js +27 -0
  46. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.js +77 -0
  47. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.scss +9 -0
  48. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/formatImages.js +7 -0
  49. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/images/ansible.png +0 -0
  50. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/images/puppet.png +0 -0
  51. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTable.js +85 -0
  52. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTableSchema.js +65 -0
  53. data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/index.js +28 -0
  54. data/webpack/src/Router/HostReports/IndexPage/IndexPage.js +88 -0
  55. data/webpack/src/Router/HostReports/IndexPage/IndexPageActions.js +55 -0
  56. data/webpack/src/Router/HostReports/IndexPage/IndexPageHelpers.js +50 -0
  57. data/webpack/src/Router/HostReports/IndexPage/IndexPageSelectors.js +86 -0
  58. data/webpack/src/Router/HostReports/IndexPage/constants.js +14 -0
  59. data/webpack/src/Router/HostReports/IndexPage/index.js +98 -0
  60. data/webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/HostReportMetrics.scss +3 -0
  61. data/webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/index.js +100 -0
  62. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Ansible.js +77 -0
  63. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Puppet.js +79 -0
  64. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/helpers.js +17 -0
  65. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/index.js +29 -0
  66. data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogsFilter/index.js +109 -0
  67. data/webpack/src/Router/HostReports/ShowPage/ShowPage.js +160 -0
  68. data/webpack/src/Router/HostReports/ShowPage/ShowPageSelectors.js +51 -0
  69. data/webpack/src/Router/HostReports/ShowPage/index.js +75 -0
  70. data/webpack/src/Router/HostReports/constants.js +15 -0
  71. data/webpack/src/Router/routes.js +23 -0
  72. data/webpack/test_setup.js +17 -0
  73. metadata +133 -0
@@ -0,0 +1,278 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class Api::V2::HostReportsControllerTest < ActionController::TestCase
4
+ context 'when user does not have permission to view hosts' do
5
+ let :host_report do
6
+ as_admin { FactoryBot.create(:host_report) }
7
+ end
8
+
9
+ setup { setup_user('view', 'host_reports') }
10
+
11
+ test 'cannot view any reports' do
12
+ get :show, params: { id: host_report.id }, session: set_session_user.merge(user: User.current.id)
13
+ assert_response :not_found
14
+ end
15
+
16
+ test 'cannot delete host reports' do
17
+ setup_user 'destroy', 'host_reports'
18
+ delete :destroy, params: { id: host_report.id }, session: set_session_user.merge(user: User.current.id)
19
+ assert_response :not_found
20
+ end
21
+ end
22
+
23
+ describe 'Non Admin User' do
24
+ def setup
25
+ User.current = users(:one) # use an unprivileged user, not apiadmin
26
+ end
27
+
28
+ def report_body
29
+ @report_body ||= read_report('foreman-web.json')
30
+ end
31
+
32
+ let :host do
33
+ as_admin { FactoryBot.create(:host) }
34
+ end
35
+
36
+ def test_create_valid
37
+ User.current = nil
38
+ post :create, params: {
39
+ host_report: {
40
+ host: host.name, body: report_body, reported_at: Time.current,
41
+ status: 0
42
+ },
43
+ }, session: set_session_user
44
+ assert_response :success
45
+ end
46
+
47
+ def test_create_invalid
48
+ User.current = nil
49
+ post :create, params: { host_report: { body: report_body } }, session: set_session_user
50
+ assert_response :unprocessable_entity
51
+ end
52
+
53
+ test 'assign keywords' do
54
+ User.current = nil
55
+ post :create, params: {
56
+ host_report: {
57
+ host: host.name, body: report_body, reported_at: Time.current,
58
+ status: 0, keywords: %w[HasError HasFailedResource]
59
+ },
60
+ }, session: set_session_user
61
+ report = ActiveSupport::JSON.decode(@response.body)
62
+ assert_response :created
63
+ refute_empty report['keywords']
64
+ end
65
+
66
+ test 're-use existing keywords' do
67
+ User.current = nil
68
+ assert_difference('ReportKeyword.count', 2) do
69
+ post :create, params: {
70
+ host_report: {
71
+ host: host.name, body: report_body, reported_at: Time.current,
72
+ status: 0, keywords: %w[HasError HasFailedResource]
73
+ },
74
+ }, session: set_session_user
75
+
76
+ post :create, params: {
77
+ host_report: {
78
+ host: host.name, body: report_body, reported_at: Time.current,
79
+ status: 0, keywords: %w[HasError HasFailedResource]
80
+ },
81
+ }, session: set_session_user
82
+ end
83
+ end
84
+
85
+ test 'when ":restrict_registered_smart_proxies" is false, HTTP requests should be able to create a report' do
86
+ Setting[:restrict_registered_smart_proxies] = false
87
+ SETTINGS[:require_ssl] = false
88
+
89
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
90
+ post :create, params: {
91
+ host_report: {
92
+ host: host.name, body: report_body, reported_at: Time.current,
93
+ status: 0
94
+ },
95
+ }
96
+ assert_nil @controller.detected_proxy
97
+ assert_response :created
98
+ end
99
+
100
+ test 'hosts with a registered smart proxy on should create a report successfully' do
101
+ Setting[:restrict_registered_smart_proxies] = true
102
+ Setting[:require_ssl_smart_proxies] = false
103
+
104
+ stub_smart_proxy_v2_features
105
+ proxy = smart_proxies(:puppetmaster)
106
+ as_admin { proxy.update_attribute(:url, 'http://configreports.foreman') }
107
+ proxy_host = URI.parse(proxy.url).host
108
+ Resolv.any_instance.stubs(:getnames).returns([proxy_host])
109
+ post :create, params: {
110
+ host_report: {
111
+ host: host.name, body: report_body, reported_at: Time.current,
112
+ status: 0
113
+ },
114
+ }
115
+ assert_equal proxy, @controller.detected_proxy
116
+ assert_response :created
117
+ end
118
+
119
+ test 'hosts without a registered smart proxy on should not be able to create a report' do
120
+ Setting[:restrict_registered_smart_proxies] = true
121
+ Setting[:require_ssl_smart_proxies] = false
122
+
123
+ Resolv.any_instance.stubs(:getnames).returns(['another.host'])
124
+ post :create, params: {
125
+ host_report: {
126
+ host: host.name, body: report_body, reported_at: Time.current,
127
+ status: 0
128
+ },
129
+ }
130
+ assert_response :forbidden
131
+ end
132
+
133
+ test 'hosts with a registered smart proxy and SSL cert should create a report successfully' do
134
+ Setting[:restrict_registered_smart_proxies] = true
135
+ Setting[:require_ssl_smart_proxies] = true
136
+
137
+ @request.env['HTTPS'] = 'on'
138
+ @request.env['SSL_CLIENT_S_DN'] = 'CN=else.where'
139
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
140
+ post :create, params: {
141
+ host_report: {
142
+ host: host.name, body: report_body, reported_at: Time.current,
143
+ status: 0
144
+ },
145
+ }
146
+ assert_response :created
147
+ end
148
+
149
+ test 'hosts without a registered smart proxy but with an SSL cert should not be able to create a report' do
150
+ Setting[:restrict_registered_smart_proxies] = true
151
+ Setting[:require_ssl_smart_proxies] = true
152
+
153
+ @request.env['HTTPS'] = 'on'
154
+ @request.env['SSL_CLIENT_S_DN'] = 'CN=another.host'
155
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
156
+ post :create, params: {
157
+ host_report: {
158
+ host: host.name, body: report_body, reported_at: Time.current,
159
+ status: 0
160
+ },
161
+ }
162
+ assert_response :forbidden
163
+ end
164
+
165
+ test 'hosts with an unverified SSL cert should not be able to create a report' do
166
+ Setting[:restrict_registered_smart_proxies] = true
167
+ Setting[:require_ssl_smart_proxies] = true
168
+
169
+ @request.env['HTTPS'] = 'on'
170
+ @request.env['SSL_CLIENT_S_DN'] = 'CN=else.where'
171
+ @request.env['SSL_CLIENT_VERIFY'] = 'FAILED'
172
+ post :create, params: {
173
+ host_report: {
174
+ host: host.name, body: report_body, reported_at: Time.current,
175
+ status: 0
176
+ },
177
+ }
178
+ assert_response :forbidden
179
+ end
180
+
181
+ test 'when "require_ssl_smart_proxies" and "require_ssl" are true, HTTP requests should not be able to create a report' do
182
+ Setting[:restrict_registered_smart_proxies] = true
183
+ Setting[:require_ssl_smart_proxies] = true
184
+ SETTINGS[:require_ssl] = true
185
+
186
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
187
+ post :create, params: {
188
+ host_report: {
189
+ host: host.name, body: report_body, reported_at: Time.current,
190
+ status: 0
191
+ },
192
+ }
193
+ assert_response :forbidden
194
+ end
195
+
196
+ test 'when "require_ssl_smart_proxies" is true and "require_ssl" is false, HTTP requests should be able to create reports' do
197
+ # since require_ssl_smart_proxies is only applicable to HTTPS connections, both should be set
198
+ Setting[:restrict_registered_smart_proxies] = true
199
+ Setting[:require_ssl_smart_proxies] = true
200
+ SETTINGS[:require_ssl] = false
201
+
202
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
203
+ post :create, params: {
204
+ host_report: {
205
+ host: host.name, body: report_body, reported_at: Time.current,
206
+ status: 0
207
+ },
208
+ }
209
+ assert_response :created
210
+ end
211
+ end
212
+
213
+ test 'should get index' do
214
+ FactoryBot.create(:host_report)
215
+ get :index
216
+ assert_response :success
217
+ refute_nil assigns(:host_reports)
218
+ reports = ActiveSupport::JSON.decode(@response.body)
219
+ refute_empty reports['results']
220
+ end
221
+
222
+ context 'with organization given' do
223
+ let(:host_report_org) { Organization.first }
224
+ let(:host_report_loc) { Location.first }
225
+ let(:reporting_host) do
226
+ FactoryBot.create(:host, location: host_report_loc, organization: host_report_org)
227
+ end
228
+ let(:host_report) do
229
+ FactoryBot.create(:host_report, host: reporting_host)
230
+ end
231
+
232
+ test 'should get host reports in organization' do
233
+ host_report.save!
234
+ get :index, params: { organization_id: host_report_org.id }
235
+ assert_response :success
236
+ refute_nil assigns(:host_reports)
237
+ reports = ActiveSupport::JSON.decode(@response.body)
238
+ refute_empty reports['results']
239
+ end
240
+ end
241
+
242
+ test 'should show individual record' do
243
+ report = FactoryBot.create(:host_report)
244
+ get :show, params: { id: report.to_param }
245
+ assert_response :success
246
+ show_response = ActiveSupport::JSON.decode(@response.body)
247
+ refute_empty show_response
248
+ end
249
+
250
+ test 'should destroy report' do
251
+ report = FactoryBot.create(:host_report)
252
+ assert_difference('HostReport.count', -1) do
253
+ delete :destroy, params: { id: report.to_param }
254
+ end
255
+ assert_response :success
256
+ refute HostReport.unscoped.find_by(id: report.id)
257
+ end
258
+
259
+ test 'should get reports for given host only' do
260
+ report = FactoryBot.create(:host_report)
261
+ get :index, params: { host_id: report.host.id }
262
+ assert_response :success
263
+ refute_nil assigns(:host_reports)
264
+ reports = ActiveSupport::JSON.decode(@response.body)
265
+ refute_empty reports['results']
266
+ assert_equal 1, reports['results'].count
267
+ end
268
+
269
+ test 'should return empty result for host with no reports' do
270
+ host = FactoryBot.create(:host)
271
+ get :index, params: { host_id: host.to_param }
272
+ assert_response :success
273
+ refute_nil assigns(:host_reports)
274
+ reports = ActiveSupport::JSON.decode(@response.body)
275
+ assert_empty reports['results']
276
+ assert_equal 0, reports['results'].count
277
+ end
278
+ end
@@ -0,0 +1,21 @@
1
+ FactoryBot.define do
2
+ factory :host_report do
3
+ host
4
+ reported_at { Time.now.utc }
5
+ status { 0 }
6
+ body { 'report data' }
7
+ end
8
+
9
+ trait :with_keyword do
10
+ transient do
11
+ name { 'HasError' }
12
+ end
13
+ after(:build) do |report, evaluator|
14
+ report.report_keyword_ids = [FactoryBot.create(:report_keyword, name: evaluator.name).id]
15
+ end
16
+ end
17
+
18
+ factory :report_keyword do
19
+ sequence(:name) { |n| "Keyword-#{n}" }
20
+ end
21
+ end