foreman_rh_cloud 13.0.9 → 13.0.10
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 +4 -4
- data/app/controllers/concerns/inventory_upload/report_actions.rb +8 -1
- data/app/controllers/foreman_inventory_upload/accounts_controller.rb +82 -7
- data/app/controllers/foreman_inventory_upload/api/tasks_controller.rb +110 -0
- data/app/controllers/foreman_inventory_upload/reports_controller.rb +41 -17
- data/app/controllers/foreman_inventory_upload/uploads_controller.rb +0 -9
- data/config/routes.rb +4 -2
- data/db/migrate/20251209163012_drop_task_output_tables.foreman_rh_cloud.rb +24 -0
- data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +1 -1
- data/lib/foreman_inventory_upload/async/host_inventory_report_job.rb +39 -0
- data/lib/foreman_inventory_upload/async/upload_report_direct_job.rb +28 -57
- data/lib/foreman_rh_cloud/plugin.rb +1 -0
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/tasks/rh_cloud_inventory.rake +4 -2
- data/package.json +1 -1
- data/test/controllers/accounts_controller_test.rb +10 -11
- data/test/controllers/insights_cloud/api/cloud_request_controller_test.rb +1 -2
- data/test/jobs/host_inventory_report_job_test.rb +161 -97
- data/test/jobs/single_host_report_job_test.rb +36 -54
- data/test/jobs/upload_report_direct_job_test.rb +132 -132
- data/test/unit/rh_cloud_permissions_test.rb +2 -0
- data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.fixtures.js +6 -6
- data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.js +49 -34
- data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListActions.js +2 -2
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/ListItem.fixtures.js +2 -2
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/ListItem.js +15 -9
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/__snapshots__/ListItem.test.js.snap +6 -5
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/ListItemStatus.fixtures.js +2 -2
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/ListItemStatus.js +10 -14
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/ListItemStatusHelper.js +9 -4
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/__tests__/__snapshots__/ListItemStatus.test.js.snap +4 -4
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountList.test.js.snap +15 -9
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListActions.test.js.snap +7 -7
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListReducer.test.js.snap +6 -6
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListSelectors.test.js.snap +12 -12
- data/webpack/ForemanInventoryUpload/Components/Dashboard/Dashboard.js +36 -132
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/Dashboard.test.js +60 -17
- data/webpack/ForemanInventoryUpload/Components/Dashboard/index.js +1 -34
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/integration.test.js.snap +0 -1
- data/webpack/ForemanInventoryUpload/Components/NavContainer/NavContainer.js +1 -26
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +2 -2
- data/webpack/ForemanInventoryUpload/Components/TabHeader/TabHeader.js +22 -9
- data/webpack/ForemanInventoryUpload/Components/TabHeader/__tests__/TabHeader.test.js +67 -4
- data/webpack/ForemanInventoryUpload/Components/TaskHistory/TaskHistory.js +140 -0
- data/webpack/ForemanInventoryUpload/Components/TaskHistory/index.js +1 -0
- data/webpack/ForemanInventoryUpload/Components/TaskHistory/taskHistory.scss +40 -0
- data/webpack/ForemanInventoryUpload/Components/TaskProgress/TaskProgress.js +340 -0
- data/webpack/ForemanInventoryUpload/Components/TaskProgress/index.js +1 -0
- data/webpack/ForemanInventoryUpload/Components/TaskProgress/taskProgress.scss +8 -0
- data/webpack/ForemanInventoryUpload/ForemanInventoryHelpers.js +2 -2
- data/webpack/ForemanInventoryUpload/ForemanInventoryUploadReducers.js +0 -2
- data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryHelpers.test.js.snap +1 -1
- data/webpack/ForemanRhCloudPages.js +0 -1
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationHelpers.js +1 -2
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +2 -4
- data/webpack/__mocks__/foremanReact/components/common/dates/RelativeDateTime.js +14 -0
- data/webpack/__tests__/ForemanRhCloudHelpers.test.js +5 -1
- metadata +10 -61
- data/app/models/task_output_line.rb +0 -2
- data/app/models/task_output_status.rb +0 -2
- data/lib/foreman_inventory_upload/async/generate_report_job.rb +0 -61
- data/lib/foreman_inventory_upload/async/progress_output.rb +0 -38
- data/lib/foreman_inventory_upload/async/shell_process.rb +0 -77
- data/test/controllers/reports_controller_test.rb +0 -21
- data/test/controllers/uploads_controller_test.rb +0 -21
- data/test/jobs/generate_report_job_test.rb +0 -146
- data/test/unit/shell_process_job_test.rb +0 -29
- data/webpack/ForemanInventoryUpload/Components/Dashboard/DashboardActions.js +0 -88
- data/webpack/ForemanInventoryUpload/Components/Dashboard/DashboardConstants.js +0 -9
- data/webpack/ForemanInventoryUpload/Components/Dashboard/DashboardReducer.js +0 -68
- data/webpack/ForemanInventoryUpload/Components/Dashboard/DashboardSelectors.js +0 -17
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardActions.test.js +0 -51
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardIntegration.test.js +0 -17
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardReducer.test.js +0 -64
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardSelectors.test.js +0 -46
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/__snapshots__/Dashboard.test.js.snap +0 -36
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/__snapshots__/DashboardActions.test.js.snap +0 -76
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/__snapshots__/DashboardReducer.test.js.snap +0 -44
- data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/__snapshots__/DashboardSelectors.test.js.snap +0 -42
- data/webpack/ForemanInventoryUpload/Components/FullScreenModal/FullScreenModal.fixtures.js +0 -0
- data/webpack/ForemanInventoryUpload/Components/FullScreenModal/FullScreenModal.js +0 -55
- data/webpack/ForemanInventoryUpload/Components/FullScreenModal/FullScreenModalHelper.js +0 -0
- data/webpack/ForemanInventoryUpload/Components/FullScreenModal/__tests__/FullScreenModal.test.js +0 -13
- data/webpack/ForemanInventoryUpload/Components/FullScreenModal/__tests__/__snapshots__/FullScreenModal.test.js.snap +0 -65
- data/webpack/ForemanInventoryUpload/Components/FullScreenModal/fullScreenModal.scss +0 -20
- data/webpack/ForemanInventoryUpload/Components/FullScreenModal/index.js +0 -1
- data/webpack/ForemanInventoryUpload/Components/ReportGenerate/ReportGenerate.fixtures.js +0 -18
- data/webpack/ForemanInventoryUpload/Components/ReportGenerate/ReportGenerate.js +0 -65
- data/webpack/ForemanInventoryUpload/Components/ReportGenerate/ReportGenerateHelper.js +0 -0
- data/webpack/ForemanInventoryUpload/Components/ReportGenerate/__tests__/ReportGenerate.test.js +0 -14
- data/webpack/ForemanInventoryUpload/Components/ReportGenerate/__tests__/__snapshots__/ReportGenerate.test.js.snap +0 -47
- data/webpack/ForemanInventoryUpload/Components/ReportGenerate/index.js +0 -1
- data/webpack/ForemanInventoryUpload/Components/ReportGenerate/reportGenerate.scss +0 -0
- data/webpack/ForemanInventoryUpload/Components/ReportUpload/ReportUpload.fixtures.js +0 -18
- data/webpack/ForemanInventoryUpload/Components/ReportUpload/ReportUpload.js +0 -46
- data/webpack/ForemanInventoryUpload/Components/ReportUpload/ReportUploadHelper.js +0 -0
- data/webpack/ForemanInventoryUpload/Components/ReportUpload/__tests__/ReportUpload.test.js +0 -14
- data/webpack/ForemanInventoryUpload/Components/ReportUpload/__tests__/__snapshots__/ReportUpload.test.js.snap +0 -47
- data/webpack/ForemanInventoryUpload/Components/ReportUpload/index.js +0 -1
- data/webpack/ForemanInventoryUpload/Components/ReportUpload/reportUpload.scss +0 -0
- data/webpack/ForemanInventoryUpload/Components/TabBody/TabBody.fixtures.js +0 -0
- data/webpack/ForemanInventoryUpload/Components/TabBody/TabBody.js +0 -31
- data/webpack/ForemanInventoryUpload/Components/TabBody/TabBodyHelper.js +0 -0
- data/webpack/ForemanInventoryUpload/Components/TabBody/__tests__/TabBody.test.js +0 -13
- data/webpack/ForemanInventoryUpload/Components/TabBody/__tests__/__snapshots__/TabBody.test.js.snap +0 -19
- data/webpack/ForemanInventoryUpload/Components/TabBody/index.js +0 -1
- data/webpack/ForemanInventoryUpload/Components/TabBody/tabBody.scss +0 -5
- data/webpack/ForemanInventoryUpload/Components/Terminal/Terminal.fixtures.js +0 -10
- data/webpack/ForemanInventoryUpload/Components/Terminal/Terminal.js +0 -110
- data/webpack/ForemanInventoryUpload/Components/Terminal/TerminalHelper.js +0 -6
- data/webpack/ForemanInventoryUpload/Components/Terminal/__tests__/Terminal.test.js +0 -34
- data/webpack/ForemanInventoryUpload/Components/Terminal/__tests__/__snapshots__/Terminal.test.js.snap +0 -98
- data/webpack/ForemanInventoryUpload/Components/Terminal/index.js +0 -1
- data/webpack/ForemanInventoryUpload/Components/Terminal/terminal.scss +0 -32
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
module ForemanInventoryUpload
|
|
2
|
-
module Async
|
|
3
|
-
class GenerateReportJob < ShellProcess
|
|
4
|
-
def self.output_label(label)
|
|
5
|
-
"report_for_#{label}"
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def plan(base_folder, organization_id, disconnected = false, hosts_filter = nil)
|
|
9
|
-
sequence do
|
|
10
|
-
super(
|
|
11
|
-
GenerateReportJob.output_label("#{organization_id}#{hosts_filter.empty? ? nil : "[#{hosts_filter.to_s.parameterize}]"}"),
|
|
12
|
-
organization_id: organization_id,
|
|
13
|
-
base_folder: base_folder,
|
|
14
|
-
hosts_filter: hosts_filter
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
unless content_disconnected?(disconnected)
|
|
18
|
-
plan_action(
|
|
19
|
-
QueueForUploadJob,
|
|
20
|
-
base_folder,
|
|
21
|
-
ForemanInventoryUpload.facts_archive_name(organization_id, hosts_filter),
|
|
22
|
-
organization_id
|
|
23
|
-
)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def rake_prefix
|
|
29
|
-
'foreman-' unless Rails.env.development?
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def command
|
|
33
|
-
"#{rake_prefix}rake rh_cloud_inventory:report:generate"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def env
|
|
37
|
-
super.merge(
|
|
38
|
-
'target' => base_folder,
|
|
39
|
-
'organization_id' => organization_id,
|
|
40
|
-
'hosts_filter' => hosts_filter
|
|
41
|
-
)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def content_disconnected?(disconnected)
|
|
45
|
-
disconnected || !Setting[:subscription_connection_enabled]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def base_folder
|
|
49
|
-
input[:base_folder]
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def organization_id
|
|
53
|
-
input[:organization_id]
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def hosts_filter
|
|
57
|
-
input[:hosts_filter]
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
module ForemanInventoryUpload
|
|
2
|
-
module Async
|
|
3
|
-
class ProgressOutput
|
|
4
|
-
def self.get(label)
|
|
5
|
-
ProgressOutput.new(label, :reader)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def self.register(label)
|
|
9
|
-
TaskOutputLine.where(label: @label).delete_all
|
|
10
|
-
ProgressOutput.new(label, :writer)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def initialize(label, mode)
|
|
14
|
-
@label = label
|
|
15
|
-
@mode = mode
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def full_output
|
|
19
|
-
TaskOutputLine.where(label: @label).order(:created_at).pluck(:line).join("\n")
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def write_line(line)
|
|
23
|
-
TaskOutputLine.create!(label: @label, line: line)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def close
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def status
|
|
30
|
-
TaskOutputStatus.where(label: @label).pluck(:status).first || ''
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def status=(status)
|
|
34
|
-
TaskOutputStatus.upsert({ label: @label, status: status }, unique_by: :label)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
require 'open3'
|
|
2
|
-
|
|
3
|
-
module ForemanInventoryUpload
|
|
4
|
-
module Async
|
|
5
|
-
class ShellProcess < ::Actions::EntryAction
|
|
6
|
-
include AsyncHelpers
|
|
7
|
-
include ::ForemanRhCloud::Async::ExponentialBackoff
|
|
8
|
-
|
|
9
|
-
def plan(instance_label, more_inputs = {})
|
|
10
|
-
clear_task_output(instance_label)
|
|
11
|
-
inputs = more_inputs.merge(instance_label: instance_label)
|
|
12
|
-
plan_self(inputs)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def try_execute
|
|
16
|
-
klass_name = self.class.name
|
|
17
|
-
logger.debug("Starting #{klass_name} with label #{instance_label}")
|
|
18
|
-
progress_output do |progress_output|
|
|
19
|
-
Open3.popen2e(hash_to_s(env), *preprocess_command(command)) do |_stdin, stdout_stderr, wait_thread|
|
|
20
|
-
progress_output.status = "Running in pid #{wait_thread.pid}"
|
|
21
|
-
|
|
22
|
-
stdout_stderr.each do |out_line|
|
|
23
|
-
progress_output.write_line(out_line)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
progress_output.status = wait_thread.value.to_s
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
logger.debug("Finished job #{klass_name} with label #{instance_label}")
|
|
30
|
-
|
|
31
|
-
assert_task_status(ProgressOutput.get(instance_label).status)
|
|
32
|
-
done!
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def command
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def progress_output
|
|
39
|
-
progress_output = ProgressOutput.register(instance_label)
|
|
40
|
-
yield(progress_output)
|
|
41
|
-
ensure
|
|
42
|
-
progress_output.close
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def env
|
|
46
|
-
{}
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def logger
|
|
50
|
-
Foreman::Logging.logger('background')
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def rescue_strategy_for_self
|
|
54
|
-
Dynflow::Action::Rescue::Fail
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def clear_task_output(label)
|
|
58
|
-
TaskOutputLine.where(label: label).delete_all
|
|
59
|
-
TaskOutputStatus.where(label: label).delete_all
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
def preprocess_command(command)
|
|
65
|
-
command.kind_of?(Array) ? command : [command]
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def instance_label
|
|
69
|
-
input[:instance_label]
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def assert_task_status(status)
|
|
73
|
-
raise Foreman::Exception.new('Process exited with an unknown status: %{status}', status: status) unless status.match?(/pid \d+ exit 0/)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
require 'test_plugin_helper'
|
|
2
|
-
|
|
3
|
-
class ReportsControllerTest < ActionController::TestCase
|
|
4
|
-
tests ForemanInventoryUpload::ReportsController
|
|
5
|
-
|
|
6
|
-
test 'Returns latest report generation status' do
|
|
7
|
-
progress_output = mock('progress_output')
|
|
8
|
-
test_org = FactoryBot.create(:organization)
|
|
9
|
-
ForemanInventoryUpload::Async::ProgressOutput
|
|
10
|
-
.expects(:get)
|
|
11
|
-
.with(ForemanInventoryUpload::Async::GenerateReportJob.output_label(test_org.id))
|
|
12
|
-
.returns(progress_output)
|
|
13
|
-
progress_output.expects(:full_output).returns('test output')
|
|
14
|
-
|
|
15
|
-
get :last, params: { organization_id: test_org.id }, session: set_session_user
|
|
16
|
-
|
|
17
|
-
assert_response :success
|
|
18
|
-
actual = JSON.parse(response.body)
|
|
19
|
-
assert_equal 'test output', actual['output']
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
require 'test_plugin_helper'
|
|
2
|
-
|
|
3
|
-
class UploadsControllerTest < ActionController::TestCase
|
|
4
|
-
tests ForemanInventoryUpload::UploadsController
|
|
5
|
-
|
|
6
|
-
test 'Returns latest upload status' do
|
|
7
|
-
progress_output = mock('progress_output')
|
|
8
|
-
test_org = FactoryBot.create(:organization)
|
|
9
|
-
ForemanInventoryUpload::Async::ProgressOutput
|
|
10
|
-
.expects(:get)
|
|
11
|
-
.with(ForemanInventoryUpload::Async::UploadReportDirectJob.output_label(test_org.id))
|
|
12
|
-
.returns(progress_output)
|
|
13
|
-
progress_output.expects(:full_output).returns('test output')
|
|
14
|
-
|
|
15
|
-
get :last, params: { organization_id: test_org.id }, session: set_session_user
|
|
16
|
-
|
|
17
|
-
assert_response :success
|
|
18
|
-
actual = JSON.parse(response.body)
|
|
19
|
-
assert_equal 'test output', actual['output']
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
require 'test_plugin_helper'
|
|
2
|
-
require 'foreman_tasks/test_helpers'
|
|
3
|
-
|
|
4
|
-
class GenerateReportJobTest < ActiveSupport::TestCase
|
|
5
|
-
include Dynflow::Testing::Factories
|
|
6
|
-
include Dynflow::Testing::Assertions
|
|
7
|
-
|
|
8
|
-
let(:organization) { FactoryBot.create(:organization) }
|
|
9
|
-
let(:base_folder) { Dir.mktmpdir }
|
|
10
|
-
|
|
11
|
-
setup do
|
|
12
|
-
# Stub settings
|
|
13
|
-
Setting.stubs(:[]).with(:subscription_connection_enabled).returns(true)
|
|
14
|
-
Setting.stubs(:[]).with("foreman_tasks_sync_task_timeout").returns(120)
|
|
15
|
-
Setting.stubs(:[]).with(:content_default_http_proxy).returns(nil)
|
|
16
|
-
Setting.stubs(:[]).with(:http_proxy).returns(nil)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
teardown do
|
|
20
|
-
FileUtils.remove_entry base_folder if Dir.exist?(base_folder)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
test 'disconnected parameter defaults to false' do
|
|
24
|
-
# When disconnected defaults to false and subscription_connection is enabled,
|
|
25
|
-
# QueueForUploadJob should be scheduled
|
|
26
|
-
action = create_and_plan_action(
|
|
27
|
-
ForemanInventoryUpload::Async::GenerateReportJob,
|
|
28
|
-
base_folder,
|
|
29
|
-
organization.id
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
assert_action_planned(action, ForemanInventoryUpload::Async::QueueForUploadJob)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
test 'disconnected parameter can be set to true explicitly' do
|
|
36
|
-
# When disconnected is explicitly true, QueueForUploadJob should NOT be scheduled
|
|
37
|
-
action = create_and_plan_action(
|
|
38
|
-
ForemanInventoryUpload::Async::GenerateReportJob,
|
|
39
|
-
base_folder,
|
|
40
|
-
organization.id,
|
|
41
|
-
true
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
refute_action_planned(action, ForemanInventoryUpload::Async::QueueForUploadJob)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
test 'disconnected parameter can be set to false explicitly' do
|
|
48
|
-
# When disconnected is explicitly false and subscription_connection is enabled,
|
|
49
|
-
# QueueForUploadJob should be scheduled
|
|
50
|
-
action = create_and_plan_action(
|
|
51
|
-
ForemanInventoryUpload::Async::GenerateReportJob,
|
|
52
|
-
base_folder,
|
|
53
|
-
organization.id,
|
|
54
|
-
false
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
assert_action_planned(action, ForemanInventoryUpload::Async::QueueForUploadJob)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
test 'skips upload when subscription_connection_enabled is false' do
|
|
61
|
-
Setting.stubs(:[]).with(:subscription_connection_enabled).returns(false)
|
|
62
|
-
|
|
63
|
-
action = create_and_plan_action(
|
|
64
|
-
ForemanInventoryUpload::Async::GenerateReportJob,
|
|
65
|
-
base_folder,
|
|
66
|
-
organization.id,
|
|
67
|
-
false
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
refute_action_planned(action, ForemanInventoryUpload::Async::QueueForUploadJob)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
test 'schedules upload when disconnected is false and subscription_connection is enabled' do
|
|
74
|
-
Setting.stubs(:[]).with(:subscription_connection_enabled).returns(true)
|
|
75
|
-
|
|
76
|
-
expected_archive_name = ForemanInventoryUpload.facts_archive_name(organization.id, nil)
|
|
77
|
-
action = create_and_plan_action(
|
|
78
|
-
ForemanInventoryUpload::Async::GenerateReportJob,
|
|
79
|
-
base_folder,
|
|
80
|
-
organization.id,
|
|
81
|
-
false
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
assert_action_planned_with(
|
|
85
|
-
action,
|
|
86
|
-
ForemanInventoryUpload::Async::QueueForUploadJob,
|
|
87
|
-
base_folder,
|
|
88
|
-
expected_archive_name,
|
|
89
|
-
organization.id
|
|
90
|
-
)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
test 'handles hosts_filter parameter' do
|
|
94
|
-
hosts_filter = 'name~test'
|
|
95
|
-
expected_archive_name = ForemanInventoryUpload.facts_archive_name(organization.id, hosts_filter)
|
|
96
|
-
|
|
97
|
-
action = create_and_plan_action(
|
|
98
|
-
ForemanInventoryUpload::Async::GenerateReportJob,
|
|
99
|
-
base_folder,
|
|
100
|
-
organization.id,
|
|
101
|
-
false,
|
|
102
|
-
hosts_filter
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
assert_action_planned_with(
|
|
106
|
-
action,
|
|
107
|
-
ForemanInventoryUpload::Async::QueueForUploadJob,
|
|
108
|
-
base_folder,
|
|
109
|
-
expected_archive_name,
|
|
110
|
-
organization.id
|
|
111
|
-
)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
test 'output_label generates correct label' do
|
|
115
|
-
label = ForemanInventoryUpload::Async::GenerateReportJob.output_label('test_org')
|
|
116
|
-
assert_equal 'report_for_test_org', label
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
test 'output_label with filter includes parameterized filter' do
|
|
120
|
-
action = create_and_plan_action(
|
|
121
|
-
ForemanInventoryUpload::Async::GenerateReportJob,
|
|
122
|
-
base_folder,
|
|
123
|
-
organization.id,
|
|
124
|
-
false,
|
|
125
|
-
'name~production'
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
# The output label should include organization id and parameterized filter
|
|
129
|
-
expected_label = "report_for_#{organization.id}[name-production]"
|
|
130
|
-
assert_equal expected_label, action.input[:instance_label]
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
test 'output_label without filter includes only organization id' do
|
|
134
|
-
action = create_and_plan_action(
|
|
135
|
-
ForemanInventoryUpload::Async::GenerateReportJob,
|
|
136
|
-
base_folder,
|
|
137
|
-
organization.id,
|
|
138
|
-
false,
|
|
139
|
-
''
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
# The output label should include only organization id when filter is empty
|
|
143
|
-
expected_label = "report_for_#{organization.id}"
|
|
144
|
-
assert_equal expected_label, action.input[:instance_label]
|
|
145
|
-
end
|
|
146
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require 'test_plugin_helper'
|
|
2
|
-
require 'foreman_tasks/test_helpers'
|
|
3
|
-
|
|
4
|
-
class ShellProcessJobTest < ActiveSupport::TestCase
|
|
5
|
-
class TestProcessJob < ForemanInventoryUpload::Async::ShellProcess
|
|
6
|
-
def command
|
|
7
|
-
'echo testing env: $testenv'
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def env
|
|
11
|
-
super.merge(
|
|
12
|
-
'testenv' => 'test_val'
|
|
13
|
-
)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
include ForemanTasks::TestHelpers::WithInThreadExecutor
|
|
18
|
-
include FolderIsolation
|
|
19
|
-
|
|
20
|
-
test 'Runs a process with environment vars' do
|
|
21
|
-
label = Foreman.uuid
|
|
22
|
-
ForemanTasks.sync_task(TestProcessJob, label)
|
|
23
|
-
|
|
24
|
-
progress_output = ForemanInventoryUpload::Async::ProgressOutput.get(label)
|
|
25
|
-
|
|
26
|
-
assert_match(/test_val/, progress_output.full_output)
|
|
27
|
-
assert_match(/exit 0/, progress_output.status)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { API } from 'foremanReact/redux/API';
|
|
2
|
-
import { selectActiveTab } from './DashboardSelectors';
|
|
3
|
-
import { inventoryUrl } from '../../ForemanInventoryHelpers';
|
|
4
|
-
import {
|
|
5
|
-
INVENTORY_POLLING_START,
|
|
6
|
-
INVENTORY_POLLING_STOP,
|
|
7
|
-
INVENTORY_POLLING,
|
|
8
|
-
INVENTORY_TAB_CHANGED,
|
|
9
|
-
INVENTORY_POLLING_ERROR,
|
|
10
|
-
INVENTORY_REPORTS_DOWNLOAD,
|
|
11
|
-
INVENTORY_TOGGLE_TERMINAL_FULL_SCREEN,
|
|
12
|
-
} from './DashboardConstants';
|
|
13
|
-
|
|
14
|
-
export const startPolling = (accountID, pollingProcessID) => ({
|
|
15
|
-
type: INVENTORY_POLLING_START,
|
|
16
|
-
payload: {
|
|
17
|
-
accountID,
|
|
18
|
-
pollingProcessID,
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
export const stopPolling = (accountID, pollingProcessID) => dispatch => {
|
|
23
|
-
clearInterval(pollingProcessID);
|
|
24
|
-
dispatch({
|
|
25
|
-
type: INVENTORY_POLLING_STOP,
|
|
26
|
-
payload: {
|
|
27
|
-
accountID,
|
|
28
|
-
},
|
|
29
|
-
});
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const fetchLogs = accountID => async (dispatch, getState) => {
|
|
33
|
-
const activeTab = selectActiveTab(getState(), accountID);
|
|
34
|
-
try {
|
|
35
|
-
const processController = activeTab === 'uploading' ? 'uploads' : 'reports';
|
|
36
|
-
const {
|
|
37
|
-
data: { output, scheduled },
|
|
38
|
-
} = await API.get(inventoryUrl(`${accountID}/${processController}/last`));
|
|
39
|
-
const outputArray = output.split('\n');
|
|
40
|
-
dispatch({
|
|
41
|
-
type: INVENTORY_POLLING,
|
|
42
|
-
payload: {
|
|
43
|
-
accountID,
|
|
44
|
-
activeTab,
|
|
45
|
-
logs: outputArray,
|
|
46
|
-
scheduled,
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
} catch (error) {
|
|
50
|
-
dispatch({
|
|
51
|
-
type: INVENTORY_POLLING_ERROR,
|
|
52
|
-
payload: {
|
|
53
|
-
accountID,
|
|
54
|
-
activeTab,
|
|
55
|
-
error: error.message,
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export const setActiveTab = (accountID, tabName) => ({
|
|
62
|
-
type: INVENTORY_TAB_CHANGED,
|
|
63
|
-
payload: {
|
|
64
|
-
accountID,
|
|
65
|
-
activeTab: tabName,
|
|
66
|
-
},
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
export const downloadReports = accountID => {
|
|
70
|
-
window.open(inventoryUrl(`${accountID}/uploads/file`), '_blank');
|
|
71
|
-
return {
|
|
72
|
-
type: INVENTORY_REPORTS_DOWNLOAD,
|
|
73
|
-
payload: {
|
|
74
|
-
accountID,
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export const toggleFullScreen = accountID => (dispatch, getState) => {
|
|
80
|
-
const activeTab = selectActiveTab(getState(), accountID);
|
|
81
|
-
dispatch({
|
|
82
|
-
type: INVENTORY_TOGGLE_TERMINAL_FULL_SCREEN,
|
|
83
|
-
payload: {
|
|
84
|
-
activeTab,
|
|
85
|
-
accountID,
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export const INVENTORY_POLLING = 'INVENTORY_POLLING';
|
|
2
|
-
export const INVENTORY_POLLING_START = 'INVENTORY_POLLING_START';
|
|
3
|
-
export const INVENTORY_POLLING_STOP = 'INVENTORY_POLLING_STOP';
|
|
4
|
-
export const INVENTORY_POLLING_ERROR = 'INVENTORY_POLLING_ERROR';
|
|
5
|
-
export const INVENTORY_TAB_CHANGED = 'INVENTORY_TAB_CHANGED';
|
|
6
|
-
export const INVENTORY_REPORTS_DOWNLOAD = 'INVENTORY_REPORTS_DOWNLOAD';
|
|
7
|
-
export const INVENTORY_PROCESS_RESTART = 'INVENTORY_PROCESS_RESTART';
|
|
8
|
-
export const INVENTORY_TOGGLE_TERMINAL_FULL_SCREEN =
|
|
9
|
-
'INVENTORY_TOGGLE_TERMINAL_FULL_SCREEN';
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import Immutable from 'seamless-immutable';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
INVENTORY_POLLING_START,
|
|
5
|
-
INVENTORY_POLLING,
|
|
6
|
-
INVENTORY_TAB_CHANGED,
|
|
7
|
-
INVENTORY_POLLING_ERROR,
|
|
8
|
-
INVENTORY_TOGGLE_TERMINAL_FULL_SCREEN,
|
|
9
|
-
} from './DashboardConstants';
|
|
10
|
-
|
|
11
|
-
const initialState = Immutable({});
|
|
12
|
-
|
|
13
|
-
export default (state = initialState, action) => {
|
|
14
|
-
const {
|
|
15
|
-
payload: {
|
|
16
|
-
accountID,
|
|
17
|
-
pollingProcessID,
|
|
18
|
-
logs,
|
|
19
|
-
error,
|
|
20
|
-
activeTab,
|
|
21
|
-
scheduled,
|
|
22
|
-
} = {},
|
|
23
|
-
} = action;
|
|
24
|
-
|
|
25
|
-
const getTabState = () =>
|
|
26
|
-
state[accountID] ? state[accountID][activeTab] : {};
|
|
27
|
-
switch (action.type) {
|
|
28
|
-
case INVENTORY_POLLING_START:
|
|
29
|
-
return state.setIn([accountID], {
|
|
30
|
-
...state[accountID],
|
|
31
|
-
pollingProcessID,
|
|
32
|
-
activeTab: 'generating',
|
|
33
|
-
});
|
|
34
|
-
case INVENTORY_POLLING:
|
|
35
|
-
return state.setIn([accountID], {
|
|
36
|
-
...state[accountID],
|
|
37
|
-
[activeTab]: {
|
|
38
|
-
...getTabState(),
|
|
39
|
-
logs,
|
|
40
|
-
scheduled,
|
|
41
|
-
error: null,
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
case INVENTORY_TAB_CHANGED:
|
|
45
|
-
return state.setIn([accountID], {
|
|
46
|
-
...state[accountID],
|
|
47
|
-
activeTab,
|
|
48
|
-
});
|
|
49
|
-
case INVENTORY_POLLING_ERROR:
|
|
50
|
-
return state.setIn([accountID], {
|
|
51
|
-
...state[accountID],
|
|
52
|
-
[activeTab]: {
|
|
53
|
-
...getTabState(),
|
|
54
|
-
error,
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
case INVENTORY_TOGGLE_TERMINAL_FULL_SCREEN:
|
|
58
|
-
return state.setIn([accountID], {
|
|
59
|
-
...state[accountID],
|
|
60
|
-
[activeTab]: {
|
|
61
|
-
...getTabState(),
|
|
62
|
-
showFullScreen: !state[accountID][activeTab].showFullScreen,
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
default:
|
|
66
|
-
return state;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { selectForemanInventoryUpload } from '../../../ForemanRhCloudSelectors';
|
|
2
|
-
|
|
3
|
-
export const selectDashboard = (state, accountID) =>
|
|
4
|
-
selectForemanInventoryUpload(state).dashboard[accountID] || {};
|
|
5
|
-
export const selectUploading = (state, accountID) =>
|
|
6
|
-
selectDashboard(state, accountID).uploading;
|
|
7
|
-
export const selectGenerating = (state, accountID) =>
|
|
8
|
-
selectDashboard(state, accountID).generating;
|
|
9
|
-
export const selectPollingProcessID = (state, accountID) =>
|
|
10
|
-
selectDashboard(state, accountID).pollingProcessID;
|
|
11
|
-
export const selectActiveTab = (state, accountID) =>
|
|
12
|
-
selectDashboard(state, accountID).activeTab || 'generating';
|
|
13
|
-
export const selectShowFullScreen = (state, accountID) => {
|
|
14
|
-
const activeTab = selectActiveTab(state, accountID);
|
|
15
|
-
const tabProperties = selectDashboard(state, accountID)[activeTab];
|
|
16
|
-
return tabProperties ? tabProperties.showFullScreen || false : false;
|
|
17
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { testActionSnapshotWithFixtures } from '@theforeman/test';
|
|
2
|
-
import { API } from 'foremanReact/redux/API';
|
|
3
|
-
import {
|
|
4
|
-
startPolling,
|
|
5
|
-
stopPolling,
|
|
6
|
-
fetchLogs,
|
|
7
|
-
setActiveTab,
|
|
8
|
-
downloadReports,
|
|
9
|
-
toggleFullScreen,
|
|
10
|
-
} from '../DashboardActions';
|
|
11
|
-
import {
|
|
12
|
-
pollingProcessID,
|
|
13
|
-
serverMock,
|
|
14
|
-
activeTab,
|
|
15
|
-
accountID,
|
|
16
|
-
} from '../Dashboard.fixtures';
|
|
17
|
-
import { rhCloudStateWrapper } from '../../../../ForemanRhCloudTestHelpers';
|
|
18
|
-
|
|
19
|
-
jest.mock('foremanReact/redux/API');
|
|
20
|
-
API.get.mockImplementation(() => serverMock);
|
|
21
|
-
|
|
22
|
-
const runWithGetState = (state, action, params) => dispatch => {
|
|
23
|
-
const getState = () => rhCloudStateWrapper({ dashboard: state });
|
|
24
|
-
action(params)(dispatch, getState);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const fixtures = {
|
|
28
|
-
'should startPolling': () => startPolling(accountID, pollingProcessID),
|
|
29
|
-
'should fetchLogs': () =>
|
|
30
|
-
runWithGetState({ activeTab: 'uploads' }, fetchLogs, accountID),
|
|
31
|
-
'should stopPolling': () => stopPolling(accountID, pollingProcessID),
|
|
32
|
-
'should setActiveTab': () => setActiveTab(accountID, activeTab),
|
|
33
|
-
'should downloadReports': () => downloadReports(accountID),
|
|
34
|
-
'should toggleFullScreen': () =>
|
|
35
|
-
runWithGetState({ activeTab: 'reports' }, toggleFullScreen, accountID),
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
describe('Dashboard actions', () => {
|
|
39
|
-
const { open } = window;
|
|
40
|
-
|
|
41
|
-
beforeAll(() => {
|
|
42
|
-
delete window.open;
|
|
43
|
-
window.open = jest.fn();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
afterAll(() => {
|
|
47
|
-
window.open = open;
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
return testActionSnapshotWithFixtures(fixtures);
|
|
51
|
-
});
|
data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardIntegration.test.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { IntegrationTestHelper } from '@theforeman/test';
|
|
3
|
-
|
|
4
|
-
import Dashboard from '../Dashboard';
|
|
5
|
-
import reducers from '../../../../ForemanRhCloudReducers';
|
|
6
|
-
import { accountID } from '../Dashboard.fixtures';
|
|
7
|
-
|
|
8
|
-
describe('Dashboard integration test', () => {
|
|
9
|
-
it('should flow', async () => {
|
|
10
|
-
const integrationTestHelper = new IntegrationTestHelper(reducers);
|
|
11
|
-
const component = integrationTestHelper.mount(
|
|
12
|
-
<Dashboard accountID={accountID} />
|
|
13
|
-
);
|
|
14
|
-
component.update();
|
|
15
|
-
/** Create a Flow test */
|
|
16
|
-
});
|
|
17
|
-
});
|