foreman_host_reports 0.0.3
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.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +545 -0
- data/app/controllers/api/v2/host_reports_controller.rb +98 -0
- data/app/controllers/concerns/foreman_host_reports/controller/parameters/host_report.rb +25 -0
- data/app/controllers/host_reports_controller.rb +46 -0
- data/app/models/concerns/foreman_host_reports/host_extensions.rb +9 -0
- data/app/models/concerns/foreman_host_reports/smart_proxy_extensions.rb +9 -0
- data/app/models/host_report.rb +85 -0
- data/app/models/report_keyword.rb +11 -0
- data/app/views/api/v2/host_reports/base.json.rabl +5 -0
- data/app/views/api/v2/host_reports/create.json.rabl +5 -0
- data/app/views/api/v2/host_reports/index.json.rabl +5 -0
- data/app/views/api/v2/host_reports/main.json.rabl +15 -0
- data/app/views/api/v2/host_reports/show.json.rabl +11 -0
- data/config/routes.rb +33 -0
- data/db/migrate/20210112183526_add_host_reports.rb +36 -0
- data/db/migrate/20210616133601_create_report_keywords.rb +12 -0
- data/lib/foreman_host_reports/engine.rb +68 -0
- data/lib/foreman_host_reports/version.rb +3 -0
- data/lib/foreman_host_reports.rb +4 -0
- data/lib/tasks/foreman_host_reports_tasks.rake +50 -0
- data/locale/Makefile +60 -0
- data/locale/en/foreman_host_reports.po +19 -0
- data/locale/foreman_host_reports.pot +19 -0
- data/locale/gemspec.rb +2 -0
- data/package.json +45 -0
- data/test/controllers/api/v2/host_reports_controller_test.rb +278 -0
- data/test/factories/foreman_host_reports_factories.rb +21 -0
- data/test/snapshots/foreman-web.json +918 -0
- data/test/test_plugin_helper.rb +11 -0
- data/test/unit/foreman_host_reports_test.rb +9 -0
- data/webpack/global_index.js +4 -0
- data/webpack/global_test_setup.js +11 -0
- data/webpack/index.js +0 -0
- data/webpack/src/Router/HostReports/Components/HostReportDeleteModal.js +50 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.js +53 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/FormatCell.scss +4 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/formatCellFormatter.js +6 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/hostReportsToShowFormatter.js +13 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/index.js +4 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/reportToShowFormatter.js +13 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/Formatters/statusFormatter.js +9 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/HostReportsToShowCell.js +32 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/ReportToShowCell.js +27 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.js +77 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/StatusCell.scss +9 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/formatImages.js +7 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/images/ansible.png +0 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/Components/images/puppet.png +0 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTable.js +85 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/HostReportsTableSchema.js +65 -0
- data/webpack/src/Router/HostReports/IndexPage/Components/HostReportsTable/index.js +28 -0
- data/webpack/src/Router/HostReports/IndexPage/IndexPage.js +88 -0
- data/webpack/src/Router/HostReports/IndexPage/IndexPageActions.js +55 -0
- data/webpack/src/Router/HostReports/IndexPage/IndexPageHelpers.js +50 -0
- data/webpack/src/Router/HostReports/IndexPage/IndexPageSelectors.js +86 -0
- data/webpack/src/Router/HostReports/IndexPage/constants.js +14 -0
- data/webpack/src/Router/HostReports/IndexPage/index.js +98 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/HostReportMetrics.scss +3 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/HostReportMetrics/index.js +100 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Ansible.js +77 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/Puppet.js +79 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/helpers.js +17 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogs/index.js +29 -0
- data/webpack/src/Router/HostReports/ShowPage/Components/ReportLogsFilter/index.js +109 -0
- data/webpack/src/Router/HostReports/ShowPage/ShowPage.js +160 -0
- data/webpack/src/Router/HostReports/ShowPage/ShowPageSelectors.js +51 -0
- data/webpack/src/Router/HostReports/ShowPage/index.js +75 -0
- data/webpack/src/Router/HostReports/constants.js +15 -0
- data/webpack/src/Router/routes.js +23 -0
- data/webpack/test_setup.js +17 -0
- 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
|