foreman_rh_cloud 2.0.4 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_inventory_upload/accounts_controller.rb +1 -0
  3. data/app/controllers/foreman_inventory_upload/uploads_controller.rb +14 -7
  4. data/app/models/setting/rh_cloud.rb +13 -0
  5. data/config/routes.rb +1 -0
  6. data/lib/foreman_inventory_upload.rb +12 -0
  7. data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +8 -0
  8. data/lib/foreman_inventory_upload/generators/archived_report.rb +6 -3
  9. data/lib/foreman_inventory_upload/generators/queries.rb +1 -0
  10. data/lib/foreman_inventory_upload/generators/slice.rb +20 -4
  11. data/lib/foreman_rh_cloud/engine.rb +4 -0
  12. data/lib/foreman_rh_cloud/version.rb +1 -1
  13. data/test/controllers/accounts_controller_test.rb +8 -3
  14. data/test/controllers/uploads_controller_test.rb +13 -0
  15. data/test/factories/inventory_upload_factories.rb +13 -13
  16. data/test/unit/slice_generator_test.rb +47 -4
  17. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.fixtures.js +2 -0
  18. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListActions.js +2 -1
  19. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListReducer.js +8 -0
  20. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListSelectors.js +2 -0
  21. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListReducer.test.js +11 -0
  22. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListSelectors.test.js +9 -1
  23. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListReducer.test.js.snap +10 -0
  24. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListSelectors.test.js.snap +5 -2
  25. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcher.fixtures.js +1 -0
  26. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcher.js +32 -0
  27. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcherActions.js +27 -0
  28. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcherConstants.js +2 -0
  29. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/AutoUploadSwitcher.test.js +14 -0
  30. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/AutoUploadSwitcherActions.test.js +14 -0
  31. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/__snapshots__/AutoUploadSwitcher.test.js.snap +38 -0
  32. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/__snapshots__/AutoUploadSwitcherActions.test.js.snap +14 -0
  33. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/autoUploadSwitcher.scss +3 -0
  34. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/index.js +17 -0
  35. data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardIntegration.test.js +2 -1
  36. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js +21 -0
  37. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageHeader.test.js +13 -0
  38. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageHeader.test.js.snap +33 -0
  39. data/webpack/ForemanInventoryUpload/Components/PageHeader/index.js +1 -0
  40. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/ScheduledRun.fixtures.js +1 -0
  41. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/ScheduledRun.js +4 -2
  42. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/__tests__/ScheduledRun.test.js +0 -1
  43. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/__tests__/__snapshots__/ScheduledRun.test.js.snap +0 -2
  44. data/webpack/ForemanInventoryUpload/Components/ScheduledRun/index.js +12 -1
  45. data/webpack/ForemanInventoryUpload/Components/TabBody/__tests__/__snapshots__/TabBody.test.js.snap +1 -1
  46. data/webpack/ForemanInventoryUpload/ForemanInventoryUpload.js +5 -4
  47. data/webpack/ForemanInventoryUpload/__snapshots__/ForemanInventoryUpload.test.js.snap +6 -5
  48. metadata +17 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f6361a25739c19a67518378257d51f67fc443839d76d7d07f5bd597f09ef15d
4
- data.tar.gz: b558ad39920b634ee4c9be77ec20f65235eb3193de374879dc85bc284a15bfa5
3
+ metadata.gz: aa962e3bc67676bb6d21b2196824ddef35ece66d0b24dad52658605446c39dfb
4
+ data.tar.gz: 8ee5a01dda9593c05b2babe5f65ee31a8a88dded967b159972351b5ee07e518a
5
5
  SHA512:
6
- metadata.gz: 83b2169b736d8c57d544b8ce53bda7e91e4741efdd384953fd32a22ac96e531282e97ef740112a7be5310ef44fc0569fe8995972304844302d0b2eb3db6215f8
7
- data.tar.gz: 3b7bbd7d76a68b5b41874472961eabd2360de0ad871705430d7549d8c44b48e5811ba9d566d74a3c0a8774b7c3b4c0c5a0f75ae57f2f38519ef528e12239c4f3
6
+ metadata.gz: 6d766ae3c9edec7b7041c73058a80c1e268e5dd2323a049fe66963ab7f313e9ce54e4e6f677b022f2c630944b9b8278bac30207fe4b1cf278cd8db3bdaa393cf
7
+ data.tar.gz: 4e4b112121137835a8a54dd3831ff293e7ba172458a1de2adb310a73afcbb605fc48bfe80456fc7e640218a051d419a98d5e0537f5fa4455ed619de110632fa8
@@ -25,6 +25,7 @@ module ForemanInventoryUpload
25
25
  ]
26
26
 
27
27
  render json: {
28
+ autoUploadEnabled: Setting[:allow_auto_inventory_upload],
28
29
  accounts: accounts,
29
30
  }, status: :ok
30
31
  end
@@ -11,14 +11,10 @@ module ForemanInventoryUpload
11
11
 
12
12
  def download_file
13
13
  filename = ForemanInventoryUpload.facts_archive_name(params[:organization_id])
14
- path = Rails.root.join(ForemanInventoryUpload.uploads_folder, filename)
15
- unless File.exist? path
16
- return throw_flash_error(
17
- "Path doesn't exist: #{path}"
18
- )
19
- end
14
+ files = Dir["{#{ForemanInventoryUpload.uploads_file_path(filename)},#{ForemanInventoryUpload.done_file_path(filename)}}"]
20
15
 
21
- send_file path, disposition: 'attachment', filename: filename
16
+ return send_file files.first, disposition: 'attachment', filename: filename unless files.empty?
17
+ throw_flash_error "File doesn't exist"
22
18
  end
23
19
 
24
20
  def throw_flash_error(message)
@@ -27,5 +23,16 @@ module ForemanInventoryUpload
27
23
  :error_msg => message
28
24
  )
29
25
  end
26
+
27
+ def auto_upload
28
+ Setting[:allow_auto_inventory_upload] = auto_upload_params
29
+ render json: {
30
+ autoUploadEnabled: Setting[:allow_auto_inventory_upload],
31
+ }
32
+ end
33
+
34
+ def auto_upload_params
35
+ ActiveModel::Type::Boolean.new.cast(params.require(:value))
36
+ end
30
37
  end
31
38
  end
@@ -0,0 +1,13 @@
1
+ class Setting::RhCloud < Setting
2
+ def self.default_settings
3
+ return unless ActiveRecord::Base.connection.table_exists?('settings')
4
+ return unless super
5
+ [
6
+ set('allow_auto_inventory_upload', N_('Allow automatic upload of the host inventory to the Red Hat cloud'), true),
7
+ ]
8
+ end
9
+
10
+ def self.humanized_category
11
+ N_('RH Cloud')
12
+ end
13
+ end
@@ -6,5 +6,6 @@ Rails.application.routes.draw do
6
6
  get ':organization_id/uploads/last', to: 'uploads#last', constraints: { organization_id: %r{[^\/]+} }
7
7
  get ':organization_id/uploads/file', to: 'uploads#download_file', constraints: { organization_id: %r{[^\/]+} }
8
8
  get 'accounts', to: 'accounts#index'
9
+ post 'auto_upload', to: 'uploads#auto_upload'
9
10
  end
10
11
  end
@@ -18,6 +18,18 @@ module ForemanInventoryUpload
18
18
  )
19
19
  end
20
20
 
21
+ def self.uploads_file_path(filename)
22
+ File.join(ForemanInventoryUpload.uploads_folder, filename)
23
+ end
24
+
25
+ def self.done_folder
26
+ File.join(ForemanInventoryUpload.uploads_folder, 'done/')
27
+ end
28
+
29
+ def self.done_file_path(filename)
30
+ File.join(ForemanInventoryUpload.done_folder, filename)
31
+ end
32
+
21
33
  def self.generated_reports_folder
22
34
  @generated_reports_folder ||= ensure_folder(
23
35
  File.join(
@@ -2,6 +2,14 @@ module ForemanInventoryUpload
2
2
  module Async
3
3
  class GenerateAllReportsJob < ::ApplicationJob
4
4
  def perform
5
+ unless Setting[:allow_auto_inventory_upload]
6
+ logger.debug(
7
+ 'The scheduled process is disabled due to the "allow_auto_inventory_upload"
8
+ setting being set to false.'
9
+ )
10
+ return
11
+ end
12
+
5
13
  organizations = Organization.unscoped.all
6
14
 
7
15
  organizations.map do |organization|
@@ -16,9 +16,9 @@ module ForemanInventoryUpload
16
16
  first = true
17
17
  host_batches.each do |hosts_batch|
18
18
  slice_id = Foreman.uuid
19
- hosts_count = hosts_batch.count
20
- @logger.info "Adding slice #{slice_id} with #{hosts_count} hosts"
21
- generate_slice(tmpdir, slice_id, hosts_batch)
19
+ @logger.info "Adding slice #{slice_id}"
20
+ hosts_count = generate_slice(tmpdir, slice_id, hosts_batch)
21
+ @logger.info "slice #{slice_id} was created with #{hosts_count} hosts"
22
22
  inner_generator.add_slice(slice_id, hosts_count, first)
23
23
  first = false
24
24
  end
@@ -43,10 +43,13 @@ module ForemanInventoryUpload
43
43
  private
44
44
 
45
45
  def generate_slice(tmpdir, slice_id, hosts_batch)
46
+ hosts_count = 0
46
47
  File.open(File.join(tmpdir, "#{slice_id}.json"), 'w') do |slice_out|
47
48
  slice_generator = ForemanInventoryUpload::Generators::Slice.new(hosts_batch, slice_out, slice_id)
48
49
  slice_generator.render
50
+ hosts_count = slice_generator.hosts_count
49
51
  end
52
+ hosts_count
50
53
  end
51
54
  end
52
55
  end
@@ -18,6 +18,7 @@ module ForemanInventoryUpload
18
18
  'uname::release',
19
19
  'lscpu::flags',
20
20
  'distribution::version',
21
+ 'distribution::id',
21
22
  ]).pluck(:name, :id)
22
23
  ]
23
24
  end
@@ -4,11 +4,13 @@ module ForemanInventoryUpload
4
4
  include FactHelpers
5
5
 
6
6
  attr_accessor :slice_id
7
+ attr_reader :hosts_count
7
8
 
8
9
  def initialize(hosts, output = [], slice_id = Foreman.uuid)
9
10
  @stream = JsonStream.new(output)
10
11
  @hosts = hosts
11
12
  @slice_id = slice_id
13
+ @hosts_count = 0
12
14
  end
13
15
 
14
16
  def render
@@ -26,7 +28,10 @@ module ForemanInventoryUpload
26
28
  hosts_batch.each do |host|
27
29
  next unless host&.subscription_facet&.pools&.first
28
30
  @stream.comma unless first
29
- first = false if report_host(host)
31
+ if report_host(host)
32
+ first = false
33
+ @hosts_count += 1
34
+ end
30
35
  end
31
36
  end
32
37
  end
@@ -36,7 +41,7 @@ module ForemanInventoryUpload
36
41
  @stream.object do
37
42
  @stream.simple_field('display_name', host.name)
38
43
  @stream.simple_field('fqdn', host.fqdn)
39
- @stream.simple_field('account', host.subscription_facet.pools.first.account_number.to_s)
44
+ @stream.simple_field('account', host.subscription_facet.pools.where.not(account_number: nil).first&.account_number&.to_s)
40
45
  @stream.simple_field('subscription_manager_id', host.subscription_facet.uuid)
41
46
  @stream.simple_field('satellite_id', host.subscription_facet.uuid)
42
47
  @stream.simple_field('bios_uuid', fact_value(host, 'dmi::system::uuid'))
@@ -65,7 +70,7 @@ module ForemanInventoryUpload
65
70
 
66
71
  @stream.array_field('tags', :last) do
67
72
  report_tag('satellite', 'satellite_instance_id', Foreman.instance_id) if Foreman.respond_to?(:instance_id)
68
- report_tag('satellite', 'organization_id', host.organization_id, :last)
73
+ report_tag('satellite', 'organization_id', host.organization_id.to_s, :last)
69
74
  end
70
75
  end
71
76
  end
@@ -105,7 +110,14 @@ module ForemanInventoryUpload
105
110
  end.join(', '))
106
111
  end
107
112
  end
108
- @stream.simple_field('os_release', fact_value(host, 'distribution::name'))
113
+ @stream.simple_field(
114
+ 'os_release',
115
+ os_release_value(
116
+ name: fact_value(host, 'distribution::name'),
117
+ version: fact_value(host, 'distribution::version'),
118
+ codename: fact_value(host, 'distribution::id')
119
+ )
120
+ )
109
121
  @stream.simple_field('os_kernel_version', fact_value(host, 'uname::release'))
110
122
  @stream.simple_field('arch', host.architecture&.name)
111
123
  @stream.simple_field('subscription_status', host.subscription_status_label)
@@ -142,6 +154,10 @@ module ForemanInventoryUpload
142
154
  @stream.simple_field('satellite_instance_id', Foreman.respond_to?(:instance_id) ? Foreman.instance_id : nil)
143
155
  @stream.simple_field('organization_id', host.organization_id, :last)
144
156
  end
157
+
158
+ def os_release_value(name:, version:, codename:)
159
+ "#{name} #{version} (#{codename})"
160
+ end
145
161
  end
146
162
  end
147
163
  end
@@ -5,6 +5,10 @@ module ForemanRhCloud
5
5
  class Engine < ::Rails::Engine
6
6
  engine_name 'foreman_rh_cloud'
7
7
 
8
+ initializer 'foreman_rh_cloud.load_default_settings', :before => :load_config_initializers do
9
+ require_dependency File.expand_path('../../app/models/setting/rh_cloud.rb', __dir__)
10
+ end
11
+
8
12
  config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
9
13
  config.autoload_paths += Dir["#{config.root}/app/helpers/concerns"]
10
14
  config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '2.0.4'.freeze
2
+ VERSION = '2.0.5'.freeze
3
3
  end
@@ -14,12 +14,17 @@ class AccountsControllerTest < ActionController::TestCase
14
14
  upload_label = ForemanInventoryUpload::Async::UploadReportJob.output_label(test_org.id)
15
15
  upload_output = ForemanInventoryUpload::Async::ProgressOutput.register(upload_label)
16
16
  upload_output.status = 'upload_status_test'
17
+ FactoryBot.create(:setting, :name => 'allow_auto_inventory_upload', :value => true)
18
+ assert_equal true, Setting[:allow_auto_inventory_upload]
17
19
 
18
20
  get :index, session: set_session_user
19
21
 
20
22
  assert_response :success
21
- actual = JSON.parse(response.body)['accounts'][test_org.id.to_s]
22
- assert_equal 'generate_status_test', actual['generate_report_status']
23
- assert_equal 'upload_status_test', actual['upload_report_status']
23
+ actual = JSON.parse(response.body)
24
+ actual_account_statuses = actual['accounts'][test_org.id.to_s]
25
+ assert_equal 'generate_status_test', actual_account_statuses['generate_report_status']
26
+ assert_equal 'upload_status_test', actual_account_statuses['upload_report_status']
27
+
28
+ assert_equal true, actual['autoUploadEnabled']
24
29
  end
25
30
  end
@@ -18,4 +18,17 @@ class UploadsControllerTest < ActionController::TestCase
18
18
  actual = JSON.parse(response.body)
19
19
  assert_equal 'test output', actual['output']
20
20
  end
21
+
22
+ test 'should update allow_auto_inventory_upload setting' do
23
+ FactoryBot.create(:setting, :name => 'allow_auto_inventory_upload', :settings_type => "boolean", :category => "Setting::RhCloud", :default => false, :value => false)
24
+
25
+ assert_equal false, Setting[:allow_auto_inventory_upload]
26
+
27
+ post :auto_upload, params: { value: true }, session: set_session_user
28
+
29
+ assert_response :success
30
+ actual = JSON.parse(response.body)
31
+ assert_equal true, actual['autoUploadEnabled']
32
+ assert_equal true, Setting[:allow_auto_inventory_upload]
33
+ end
21
34
  end
@@ -1,16 +1,16 @@
1
1
  # redefine katello factories, as long as katello is not compatible with dynamic properties
2
2
  FactoryBot.define do
3
3
  factory :katello_organization, :class => "Organization" do
4
- type {"Organization"}
4
+ type { "Organization" }
5
5
  sequence(:name) { |n| "Organization#{n}" }
6
6
  sequence(:label) { |n| "org#{n}" }
7
7
  sequence(:id) { |n| n }
8
8
 
9
9
  trait :acme_corporation do
10
- name {"ACME_Corporation"}
11
- type {"Organization"}
12
- description {"This is the first Organization."}
13
- label {"acme_corporation_label"}
10
+ name { "ACME_Corporation" }
11
+ type { "Organization" }
12
+ description { "This is the first Organization." }
13
+ label { "acme_corporation_label" }
14
14
  end
15
15
 
16
16
  trait :with_library do
@@ -24,11 +24,11 @@ end
24
24
  FactoryBot.define do
25
25
  factory :katello_content_view, :class => Katello::ContentView do
26
26
  sequence(:name) { |n| "Database#{n}" }
27
- description {"This content view is for database content"}
27
+ description { "This content view is for database content" }
28
28
  association :organization, :factory => :katello_organization
29
29
 
30
30
  trait :composite do
31
- composite {true}
31
+ composite { true }
32
32
  end
33
33
  end
34
34
  end
@@ -50,23 +50,23 @@ end
50
50
  FactoryBot.define do
51
51
  factory :katello_subscription_facets, :aliases => [:subscription_facet], :class => ::Katello::Host::SubscriptionFacet do
52
52
  sequence(:uuid) { |n| "uuid-#{n}-#{rand(500)}" }
53
- facts { {'memory.memtotal' => "12 GB"} }
53
+ facts { { 'memory.memtotal' => "12 GB" } }
54
54
  end
55
55
  end
56
56
 
57
57
  FactoryBot.define do
58
58
  factory :katello_pool, :class => Katello::Pool do
59
- active {true}
60
- end_date {Date.today + 1.year}
59
+ active { true }
60
+ end_date { Date.today + 1.year }
61
61
  end
62
62
  end
63
63
 
64
64
  FactoryBot.modify do
65
65
  factory :host do
66
66
  transient do
67
- content_view {nil}
68
- lifecycle_environment {nil}
69
- content_source {nil}
67
+ content_view { nil }
68
+ lifecycle_environment { nil }
69
+ content_source { nil }
70
70
  end
71
71
 
72
72
  trait :with_content do
@@ -17,6 +17,8 @@ class ReportGeneratorTest < ActiveSupport::TestCase
17
17
  )
18
18
 
19
19
  @host.subscription_facet.pools << FactoryBot.create(:katello_pool, account_number: '1234', cp_id: 1)
20
+
21
+ ForemanInventoryUpload::Generators::Queries.instance_variable_set(:@fact_names, nil)
20
22
  end
21
23
 
22
24
  def interesting_facts
@@ -30,9 +32,11 @@ class ReportGeneratorTest < ActiveSupport::TestCase
30
32
  'dmi::bios::vendor',
31
33
  'dmi::bios::version',
32
34
  'dmi::bios::relase_date',
33
- 'distribution::name',
34
35
  'uname::release',
35
36
  'lscpu::flags',
37
+ 'distribution::name',
38
+ 'distribution::version',
39
+ 'distribution::id',
36
40
  ]
37
41
  end
38
42
 
@@ -56,6 +60,7 @@ class ReportGeneratorTest < ActiveSupport::TestCase
56
60
  assert_equal @host.name, actual_host['display_name']
57
61
  assert_equal @host.fqdn, actual_host['fqdn']
58
62
  assert_equal '1234', actual_host['account']
63
+ assert_equal 1, generator.hosts_count
59
64
  end
60
65
 
61
66
  test 'generates a report with satellite facts' do
@@ -72,13 +77,13 @@ class ReportGeneratorTest < ActiveSupport::TestCase
72
77
  assert_equal 'satellite-id', satellite_facts['satellite_instance_id']
73
78
  assert_equal @host.organization_id, satellite_facts['organization_id']
74
79
 
75
- instance_id_tag = actual['hosts'].first['tags'].find { |tag| tag['namespace'] == 'satellite' && tag['key'] == 'satellite_instance_id'}
80
+ instance_id_tag = actual['hosts'].first['tags'].find { |tag| tag['namespace'] == 'satellite' && tag['key'] == 'satellite_instance_id' }
76
81
  assert_not_nil instance_id_tag
77
82
  assert_equal 'satellite-id', instance_id_tag['value']
78
83
 
79
- org_id_tag = actual['hosts'].first['tags'].find { |tag| tag['namespace'] == 'satellite' && tag['key'] == 'organization_id'}
84
+ org_id_tag = actual['hosts'].first['tags'].find { |tag| tag['namespace'] == 'satellite' && tag['key'] == 'organization_id' }
80
85
  assert_not_nil org_id_tag
81
- assert_equal @host.organization_id, org_id_tag['value']
86
+ assert_equal @host.organization_id.to_s, org_id_tag['value']
82
87
 
83
88
  version = satellite_facts['satellite_version']
84
89
  if defined?(ForemanThemeSatellite)
@@ -158,6 +163,7 @@ class ReportGeneratorTest < ActiveSupport::TestCase
158
163
  assert_equal @host.name, actual_host['display_name']
159
164
  assert_equal @host.fqdn, actual_host['fqdn']
160
165
  assert_equal '1234', actual_host['account']
166
+ assert_equal 1, generator.hosts_count
161
167
  end
162
168
 
163
169
  test 'shows system_memory_bytes in bytes' do
@@ -174,4 +180,41 @@ class ReportGeneratorTest < ActiveSupport::TestCase
174
180
  assert_not_nil(actual_profile = actual_host['system_profile'])
175
181
  assert_equal 1024, actual_profile['system_memory_bytes']
176
182
  end
183
+
184
+ test 'reports an account for hosts with multiple pools' do
185
+ first_pool = @host.subscription_facet.pools.first
186
+ second_pool = FactoryBot.create(:katello_pool, account_number: nil, cp_id: 2)
187
+ @host.subscription_facet.pools = []
188
+ @host.subscription_facet.save!
189
+ @host.subscription_facet.pools << first_pool
190
+ @host.subscription_facet.pools << second_pool
191
+
192
+ batch = Host.where(id: @host.id).in_batches.first
193
+ generator = ForemanInventoryUpload::Generators::Slice.new(batch, [], 'slice_123')
194
+
195
+ json_str = generator.render
196
+ actual = JSON.parse(json_str.join("\n"))
197
+
198
+ assert_equal 'slice_123', actual['report_slice_id']
199
+ assert_not_nil(actual_host = actual['hosts'].first)
200
+ assert_not_nil(actual_host['account'])
201
+ assert_not_empty(actual_host['account'])
202
+ end
203
+
204
+ test 'Generates os_release with version and id' do
205
+ FactoryBot.create(:fact_value, fact_name: fact_names['distribution::name'], value: 'Red Hat Test Linux', host: @host)
206
+ FactoryBot.create(:fact_value, fact_name: fact_names['distribution::version'], value: '7.1', host: @host)
207
+ FactoryBot.create(:fact_value, fact_name: fact_names['distribution::id'], value: 'TestId', host: @host)
208
+
209
+ batch = Host.where(id: @host.id).in_batches.first
210
+ generator = ForemanInventoryUpload::Generators::Slice.new(batch, [], 'slice_123')
211
+
212
+ json_str = generator.render
213
+ actual = JSON.parse(json_str.join("\n"))
214
+
215
+ assert_equal 'slice_123', actual['report_slice_id']
216
+ assert_not_nil(actual_host = actual['hosts'].first)
217
+ assert_not_nil(actual_profile = actual_host['system_profile'])
218
+ assert_equal 'Red Hat Test Linux 7.1 (TestId)', actual_profile['os_release']
219
+ end
177
220
  end
@@ -28,6 +28,8 @@ export const accountID = 'user@redhat.com';
28
28
 
29
29
  export const processStatusName = 'upload_report_status';
30
30
 
31
+ export const autoUploadEnabled = true;
32
+
31
33
  export const props = {
32
34
  accounts,
33
35
  fetchAccountsStatus: noop,
@@ -10,12 +10,13 @@ import {
10
10
  export const fetchAccountsStatus = () => async dispatch => {
11
11
  try {
12
12
  const {
13
- data: { accounts },
13
+ data: { accounts, autoUploadEnabled },
14
14
  } = await API.get('accounts');
15
15
  dispatch({
16
16
  type: INVENTORY_ACCOUNT_STATUS_POLLING,
17
17
  payload: {
18
18
  accounts,
19
+ autoUploadEnabled,
19
20
  },
20
21
  });
21
22
  } catch (error) {
@@ -5,6 +5,7 @@ import {
5
5
  INVENTORY_ACCOUNT_STATUS_POLLING_START,
6
6
  INVENTORY_PROCESS_RESTART,
7
7
  } from './AccountListConstants';
8
+ import { AUTO_UPLOAD_TOGGLE } from '../AutoUploadSwitcher/AutoUploadSwitcherConstants';
8
9
 
9
10
  const initialState = Immutable({
10
11
  accounts: {},
@@ -20,6 +21,7 @@ export default (state = initialState, action) => {
20
21
  accounts,
21
22
  accountID,
22
23
  processStatusName,
24
+ autoUploadEnabled,
23
25
  } = {},
24
26
  } = action;
25
27
 
@@ -28,6 +30,7 @@ export default (state = initialState, action) => {
28
30
  return state.merge({
29
31
  ...state,
30
32
  accounts,
33
+ autoUploadEnabled,
31
34
  error: null,
32
35
  });
33
36
  case INVENTORY_ACCOUNT_STATUS_POLLING_ERROR:
@@ -49,6 +52,11 @@ export default (state = initialState, action) => {
49
52
  [processStatusName]: 'Restarting...',
50
53
  },
51
54
  });
55
+ case AUTO_UPLOAD_TOGGLE:
56
+ return state.merge({
57
+ ...state,
58
+ autoUploadEnabled,
59
+ });
52
60
  default:
53
61
  return state;
54
62
  }
@@ -6,3 +6,5 @@ export const selectAccounts = state => selectAccountsList(state).accounts;
6
6
  export const selectPollingProcessID = state =>
7
7
  selectAccountsList(state).pollingProcessID;
8
8
  export const selectError = state => selectAccountsList(state).error;
9
+ export const selectAutoUploadEnabled = state =>
10
+ selectAccountsList(state).autoUploadEnabled;
@@ -14,7 +14,9 @@ import {
14
14
  pollingProcessID,
15
15
  accountID,
16
16
  processStatusName,
17
+ autoUploadEnabled,
17
18
  } from '../AccountList.fixtures';
19
+ import { AUTO_UPLOAD_TOGGLE } from '../../AutoUploadSwitcher/AutoUploadSwitcherConstants';
18
20
 
19
21
  const fixtures = {
20
22
  'should return the initial state': {},
@@ -23,6 +25,7 @@ const fixtures = {
23
25
  type: INVENTORY_ACCOUNT_STATUS_POLLING,
24
26
  payload: {
25
27
  accounts,
28
+ autoUploadEnabled,
26
29
  },
27
30
  },
28
31
  },
@@ -54,6 +57,14 @@ const fixtures = {
54
57
  },
55
58
  },
56
59
  },
60
+ 'should handle AUTO_UPLOAD_TOGGLE': {
61
+ action: {
62
+ type: AUTO_UPLOAD_TOGGLE,
63
+ payload: {
64
+ autoUploadEnabled,
65
+ },
66
+ },
67
+ },
57
68
  };
58
69
 
59
70
  describe('AccountList reducer', () =>
@@ -3,14 +3,20 @@ import {
3
3
  selectAccountsList,
4
4
  selectAccounts,
5
5
  selectPollingProcessID,
6
+ selectAutoUploadEnabled,
6
7
  } from '../AccountListSelectors';
7
- import { pollingProcessID, accounts } from '../AccountList.fixtures';
8
+ import {
9
+ pollingProcessID,
10
+ accounts,
11
+ autoUploadEnabled,
12
+ } from '../AccountList.fixtures';
8
13
 
9
14
  const state = {
10
15
  ForemanInventoryUpload: {
11
16
  accountsList: {
12
17
  accounts,
13
18
  pollingProcessID,
19
+ autoUploadEnabled,
14
20
  },
15
21
  },
16
22
  };
@@ -20,6 +26,8 @@ const fixtures = {
20
26
  'should return AccountList accounts': () => selectAccounts(state),
21
27
  'should return AccountList pollingProcessID': () =>
22
28
  selectPollingProcessID(state),
29
+ 'should return AccountList autoUploadEnabled': () =>
30
+ selectAutoUploadEnabled(state),
23
31
  };
24
32
 
25
33
  describe('AccountList selectors', () =>
@@ -1,5 +1,14 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`AccountList reducer should handle AUTO_UPLOAD_TOGGLE 1`] = `
4
+ Object {
5
+ "accounts": Object {},
6
+ "autoUploadEnabled": true,
7
+ "error": null,
8
+ "pollingProcessID": 0,
9
+ }
10
+ `;
11
+
3
12
  exports[`AccountList reducer should handle INVENTORY_ACCOUNT_STATUS_POLLING 1`] = `
4
13
  Object {
5
14
  "accounts": Object {
@@ -19,6 +28,7 @@ Object {
19
28
  "upload_report_status": "success",
20
29
  },
21
30
  },
31
+ "autoUploadEnabled": true,
22
32
  "error": null,
23
33
  "pollingProcessID": 0,
24
34
  }
@@ -1,7 +1,5 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`AccountList selectors should return AccountList pollingProcessID 1`] = `0`;
4
-
5
3
  exports[`AccountList selectors should return AccountList accounts 1`] = `
6
4
  Object {
7
5
  "Account1": Object {
@@ -22,6 +20,10 @@ Object {
22
20
  }
23
21
  `;
24
22
 
23
+ exports[`AccountList selectors should return AccountList autoUploadEnabled 1`] = `true`;
24
+
25
+ exports[`AccountList selectors should return AccountList pollingProcessID 1`] = `0`;
26
+
25
27
  exports[`AccountList selectors should return AccountsList 1`] = `
26
28
  Object {
27
29
  "accounts": Object {
@@ -41,6 +43,7 @@ Object {
41
43
  "upload_report_status": "success",
42
44
  },
43
45
  },
46
+ "autoUploadEnabled": true,
44
47
  "pollingProcessID": 0,
45
48
  }
46
49
  `;
@@ -0,0 +1 @@
1
+ export const handleToggleResponse = { data: { autoUploadEnabled: true } };
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Switch, FieldLevelHelp } from 'patternfly-react';
4
+ import { translate as __ } from 'foremanReact/common/I18n';
5
+ import './autoUploadSwitcher.scss';
6
+
7
+ const AutoUploadSwitcher = ({ autoUploadEnabled, handleToggle }) => (
8
+ <div className="auto_upload_switcher">
9
+ <Switch
10
+ size="mini"
11
+ value={autoUploadEnabled}
12
+ onChange={() => handleToggle(autoUploadEnabled)}
13
+ />
14
+ <FieldLevelHelp
15
+ content={__(
16
+ 'Enable automatic upload of your host inventory to the Red Hat cloud'
17
+ )}
18
+ />
19
+ <span>Allow Auto Upload</span>
20
+ </div>
21
+ );
22
+
23
+ AutoUploadSwitcher.propTypes = {
24
+ autoUploadEnabled: PropTypes.bool,
25
+ handleToggle: PropTypes.func.isRequired,
26
+ };
27
+
28
+ AutoUploadSwitcher.defaultProps = {
29
+ autoUploadEnabled: true,
30
+ };
31
+
32
+ export default AutoUploadSwitcher;
@@ -0,0 +1,27 @@
1
+ import API from 'foremanReact/API';
2
+ import {
3
+ AUTO_UPLOAD_TOGGLE,
4
+ AUTO_UPLOAD_TOGGLE_ERROR,
5
+ } from './AutoUploadSwitcherConstants';
6
+
7
+ export const handleToggle = currentAutoUploadEnabled => async dispatch => {
8
+ const toggledAutoUploadEnabled = !currentAutoUploadEnabled;
9
+ try {
10
+ const {
11
+ data: { autoUploadEnabled },
12
+ } = await API.post('auto_upload', { value: toggledAutoUploadEnabled });
13
+ dispatch({
14
+ type: AUTO_UPLOAD_TOGGLE,
15
+ payload: {
16
+ autoUploadEnabled,
17
+ },
18
+ });
19
+ } catch (error) {
20
+ dispatch({
21
+ type: AUTO_UPLOAD_TOGGLE_ERROR,
22
+ payload: {
23
+ error: error.message,
24
+ },
25
+ });
26
+ }
27
+ };
@@ -0,0 +1,2 @@
1
+ export const AUTO_UPLOAD_TOGGLE = 'AUTO_UPLOAD_TOGGLE';
2
+ export const AUTO_UPLOAD_TOGGLE_ERROR = 'AUTO_UPLOAD_TOGGLE_ERROR';
@@ -0,0 +1,14 @@
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
+ import { noop } from 'patternfly-react';
3
+
4
+ import AutoUploadSwitcher from '../AutoUploadSwitcher';
5
+
6
+ const fixtures = {
7
+ 'render with props': { autoUploadEnabled: true, handleToggle: noop },
8
+ /** fixtures, props for the component */
9
+ };
10
+
11
+ describe('AutoUploadSwitcher', () => {
12
+ describe('rendering', () =>
13
+ testComponentSnapshotsWithFixtures(AutoUploadSwitcher, fixtures));
14
+ });
@@ -0,0 +1,14 @@
1
+ import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
+ import API from 'foremanReact/API';
3
+ import { handleToggle } from '../AutoUploadSwitcherActions';
4
+ import { handleToggleResponse } from '../AutoUploadSwitcher.fixtures';
5
+
6
+ jest.mock('foremanReact/API');
7
+ API.post.mockImplementation(async () => handleToggleResponse);
8
+
9
+ const fixtures = {
10
+ 'should handleToggle': () => handleToggle(),
11
+ };
12
+
13
+ describe('AutoUploadSwitcher actions', () =>
14
+ testActionSnapshotWithFixtures(fixtures));
@@ -0,0 +1,38 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`AutoUploadSwitcher rendering render with props 1`] = `
4
+ <div
5
+ className="auto_upload_switcher"
6
+ >
7
+ <Switch
8
+ animate={true}
9
+ baseClass="bootstrap-switch"
10
+ bsSize={null}
11
+ defaultValue={true}
12
+ disabled={false}
13
+ handleWidth="auto"
14
+ inverse={false}
15
+ labelText=" "
16
+ labelWidth="auto"
17
+ offColor="default"
18
+ offText="OFF"
19
+ onChange={[Function]}
20
+ onColor="primary"
21
+ onText="ON"
22
+ readonly={false}
23
+ size="mini"
24
+ tristate={false}
25
+ value={true}
26
+ wrapperClass="wrapper"
27
+ />
28
+ <FieldLevelHelp
29
+ buttonClass=""
30
+ content="Enable automatic upload of your host inventory to the Red Hat cloud"
31
+ placement="top"
32
+ rootClose={true}
33
+ />
34
+ <span>
35
+ Allow Auto Upload
36
+ </span>
37
+ </div>
38
+ `;
@@ -0,0 +1,14 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`AutoUploadSwitcher actions should handleToggle 1`] = `
4
+ Array [
5
+ Array [
6
+ Object {
7
+ "payload": Object {
8
+ "autoUploadEnabled": true,
9
+ },
10
+ "type": "AUTO_UPLOAD_TOGGLE",
11
+ },
12
+ ],
13
+ ]
14
+ `;
@@ -0,0 +1,3 @@
1
+ .auto_upload_switcher {
2
+ float: right;
3
+ }
@@ -0,0 +1,17 @@
1
+ import { bindActionCreators } from 'redux';
2
+ import { connect } from 'react-redux';
3
+
4
+ import * as actions from './AutoUploadSwitcherActions';
5
+ import AutoUploadSwitcher from './AutoUploadSwitcher';
6
+ import { selectAutoUploadEnabled } from '../AccountList/AccountListSelectors';
7
+
8
+ // map state to props
9
+ const mapStateToProps = state => ({
10
+ autoUploadEnabled: selectAutoUploadEnabled(state),
11
+ });
12
+
13
+ // map action dispatchers to props
14
+ const mapDispatchToProps = dispatch => bindActionCreators(actions, dispatch);
15
+
16
+ // export connected component
17
+ export default connect(mapStateToProps, mapDispatchToProps)(AutoUploadSwitcher);
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { IntegrationTestHelper } from '@theforeman/test';
3
3
 
4
- import Dashboard, { reducers } from '../index';
4
+ import Dashboard from '../Dashboard';
5
+ import reducers from '../../../ForemanInventoryUploadReducers';
5
6
  import { accountID } from '../Dashboard.fixtures';
6
7
 
7
8
  describe('Dashboard integration test', () => {
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { Grid } from 'patternfly-react';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import AutoUploadSwitcher from '../AutoUploadSwitcher';
5
+
6
+ const PageHeader = () => (
7
+ <React.Fragment>
8
+ <Grid.Row>
9
+ <Grid.Col xs={12}>
10
+ <h1>{__('Red Hat Inventory Uploads')}</h1>
11
+ </Grid.Col>
12
+ </Grid.Row>
13
+ <Grid.Row>
14
+ <Grid.Col xs={4} xsOffset={8}>
15
+ <AutoUploadSwitcher />
16
+ </Grid.Col>
17
+ </Grid.Row>
18
+ </React.Fragment>
19
+ );
20
+
21
+ export default PageHeader;
@@ -0,0 +1,13 @@
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
+
3
+ import PageHeader from '../PageHeader';
4
+
5
+ const fixtures = {
6
+ 'render without Props': {},
7
+ /** fixtures, props for the component */
8
+ };
9
+
10
+ describe('PageHeader', () => {
11
+ describe('rendering', () =>
12
+ testComponentSnapshotsWithFixtures(PageHeader, fixtures));
13
+ });
@@ -0,0 +1,33 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`PageHeader rendering render without Props 1`] = `
4
+ <Fragment>
5
+ <Row
6
+ bsClass="row"
7
+ componentClass="div"
8
+ >
9
+ <Col
10
+ bsClass="col"
11
+ componentClass="div"
12
+ xs={12}
13
+ >
14
+ <h1>
15
+ Red Hat Inventory Uploads
16
+ </h1>
17
+ </Col>
18
+ </Row>
19
+ <Row
20
+ bsClass="row"
21
+ componentClass="div"
22
+ >
23
+ <Col
24
+ bsClass="col"
25
+ componentClass="div"
26
+ xs={4}
27
+ xsOffset={8}
28
+ >
29
+ <Connect(AutoUploadSwitcher) />
30
+ </Col>
31
+ </Row>
32
+ </Fragment>
33
+ `;
@@ -0,0 +1 @@
1
+ export { default } from './PageHeader';
@@ -1,3 +1,4 @@
1
1
  export const props = {
2
2
  date: '2019-08-21T16:14:16.520+03:00',
3
+ autoUploadEnabled: true,
3
4
  };
@@ -5,8 +5,8 @@ import { FormattedRelative } from 'react-intl';
5
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
6
  import './scheduledRun.scss';
7
7
 
8
- const ScheduledRun = ({ date }) =>
9
- date ? (
8
+ const ScheduledRun = ({ date, autoUploadEnabled }) =>
9
+ autoUploadEnabled && date ? (
10
10
  <Grid.Col sm={12} className="scheduled_run">
11
11
  <p>
12
12
  <Icon name="calendar" />
@@ -18,10 +18,12 @@ const ScheduledRun = ({ date }) =>
18
18
 
19
19
  ScheduledRun.propTypes = {
20
20
  date: PropTypes.string,
21
+ autoUploadEnabled: PropTypes.bool,
21
22
  };
22
23
 
23
24
  ScheduledRun.defaultProps = {
24
25
  date: null,
26
+ autoUploadEnabled: true,
25
27
  };
26
28
 
27
29
  export default ScheduledRun;
@@ -4,7 +4,6 @@ import ScheduledRun from '../ScheduledRun';
4
4
  import { props } from '../ScheduledRun.fixtures';
5
5
 
6
6
  const fixtures = {
7
- 'render without Props': {},
8
7
  'render with Props': props,
9
8
  };
10
9
 
@@ -21,5 +21,3 @@ exports[`ScheduledRun rendering render with Props 1`] = `
21
21
  </p>
22
22
  </Col>
23
23
  `;
24
-
25
- exports[`ScheduledRun rendering render without Props 1`] = `""`;
@@ -1 +1,12 @@
1
- export { default } from './ScheduledRun';
1
+ import { connect } from 'react-redux';
2
+
3
+ import ScheduledRun from './ScheduledRun';
4
+ import { selectAutoUploadEnabled } from '../AccountList/AccountListSelectors';
5
+
6
+ // map state to props
7
+ const mapStateToProps = state => ({
8
+ autoUploadEnabled: selectAutoUploadEnabled(state),
9
+ });
10
+
11
+ // export connected component
12
+ export default connect(mapStateToProps)(ScheduledRun);
@@ -12,7 +12,7 @@ exports[`TabBody rendering render without Props 1`] = `
12
12
  exitCode=""
13
13
  logs={null}
14
14
  />
15
- <ScheduledRun
15
+ <Connect(ScheduledRun)
16
16
  date={null}
17
17
  />
18
18
  </Row>
@@ -1,14 +1,15 @@
1
1
  import React from 'react';
2
2
  import { IntlProvider } from 'react-intl';
3
- import { translate as __ } from 'foremanReact/common/I18n';
3
+ import { Grid } from 'patternfly-react';
4
4
  import AccountList from './Components/AccountList';
5
+ import PageHeader from './Components/PageHeader';
5
6
 
6
7
  const ForemanInventoryUpload = () => (
7
8
  <IntlProvider locale={navigator.language}>
8
- <div className="inventory-upload">
9
- <h1>{__('Red Hat Inventory Uploads')}</h1>
9
+ <Grid fluid className="inventory-upload">
10
+ <PageHeader />
10
11
  <AccountList />
11
- </div>
12
+ </Grid>
12
13
  </IntlProvider>
13
14
  );
14
15
 
@@ -4,13 +4,14 @@ exports[`ForemanInventoryUpload render without Props 1`] = `
4
4
  <IntlProvider
5
5
  locale="en-US"
6
6
  >
7
- <div
7
+ <Grid
8
+ bsClass="container"
8
9
  className="inventory-upload"
10
+ componentClass="div"
11
+ fluid={true}
9
12
  >
10
- <h1>
11
- Red Hat Inventory Uploads
12
- </h1>
13
+ <PageHeader />
13
14
  <Connect(AccountList) />
14
- </div>
15
+ </Grid>
15
16
  </IntlProvider>
16
17
  `;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_rh_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Red Hat Cloud team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-09 00:00:00.000000000 Z
11
+ date: 2020-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: katello
@@ -109,6 +109,7 @@ files:
109
109
  - app/controllers/foreman_inventory_upload/reports_controller.rb
110
110
  - app/controllers/foreman_inventory_upload/uploads_controller.rb
111
111
  - app/helpers/foreman_inventory_upload_helper.rb
112
+ - app/models/setting/rh_cloud.rb
112
113
  - app/views/foreman_inventory_upload/layouts/react.html.erb
113
114
  - config/routes.rb
114
115
  - lib/foreman_inventory_upload.rb
@@ -191,6 +192,16 @@ files:
191
192
  - webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListSelectors.test.js.snap
192
193
  - webpack/ForemanInventoryUpload/Components/AccountList/accountList.scss
193
194
  - webpack/ForemanInventoryUpload/Components/AccountList/index.js
195
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcher.fixtures.js
196
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcher.js
197
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcherActions.js
198
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcherConstants.js
199
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/AutoUploadSwitcher.test.js
200
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/AutoUploadSwitcherActions.test.js
201
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/__snapshots__/AutoUploadSwitcher.test.js.snap
202
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/__snapshots__/AutoUploadSwitcherActions.test.js.snap
203
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/autoUploadSwitcher.scss
204
+ - webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/index.js
194
205
  - webpack/ForemanInventoryUpload/Components/Dashboard/Dashboard.fixtures.js
195
206
  - webpack/ForemanInventoryUpload/Components/Dashboard/Dashboard.js
196
207
  - webpack/ForemanInventoryUpload/Components/Dashboard/Dashboard.stories.js
@@ -231,6 +242,10 @@ files:
231
242
  - webpack/ForemanInventoryUpload/Components/NavContainer/__tests__/__snapshots__/NavContainer.test.js.snap
232
243
  - webpack/ForemanInventoryUpload/Components/NavContainer/index.js
233
244
  - webpack/ForemanInventoryUpload/Components/NavContainer/navContainer.scss
245
+ - webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js
246
+ - webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageHeader.test.js
247
+ - webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageHeader.test.js.snap
248
+ - webpack/ForemanInventoryUpload/Components/PageHeader/index.js
234
249
  - webpack/ForemanInventoryUpload/Components/ReportGenerate/ReportGenerate.fixtures.js
235
250
  - webpack/ForemanInventoryUpload/Components/ReportGenerate/ReportGenerate.js
236
251
  - webpack/ForemanInventoryUpload/Components/ReportGenerate/ReportGenerateHelper.js