foreman_rh_cloud 2.0.6 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_inventory_upload/accounts_controller.rb +2 -6
  3. data/app/controllers/foreman_rh_cloud/react_controller.rb +8 -0
  4. data/app/models/setting/rh_cloud.rb +1 -0
  5. data/app/views/foreman_rh_cloud/react/inventory_upload.html.erb +1 -0
  6. data/app/views/{foreman_inventory_upload/layouts/react.html.erb → layouts/foreman_rh_cloud/application.html.erb} +2 -2
  7. data/config/routes.rb +4 -1
  8. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +43 -0
  9. data/lib/foreman_inventory_upload/generators/queries.rb +5 -0
  10. data/lib/foreman_inventory_upload/generators/slice.rb +2 -1
  11. data/lib/foreman_rh_cloud/engine.rb +16 -4
  12. data/lib/foreman_rh_cloud/version.rb +1 -1
  13. data/test/unit/slice_generator_test.rb +132 -0
  14. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.fixtures.js +6 -2
  15. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.js +13 -10
  16. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListActions.js +3 -2
  17. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListHelper.js +10 -0
  18. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListSelectors.js +1 -1
  19. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/EmptyResults.js +15 -0
  20. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/__tests__/EmptyResults.test.js +13 -0
  21. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/__tests__/__snapshots__/EmptyResults.test.js.snap +18 -0
  22. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/emptyResults.scss +7 -0
  23. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/index.js +1 -0
  24. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/ListItem.js +1 -4
  25. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountList.test.js +1 -0
  26. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListHelper.test.js +12 -0
  27. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListIntegration.test.js +1 -1
  28. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListSelectors.test.js +7 -8
  29. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountList.test.js.snap +2 -3
  30. data/webpack/ForemanInventoryUpload/Components/AccountList/index.js +2 -0
  31. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcherActions.js +4 -1
  32. data/webpack/ForemanInventoryUpload/Components/Dashboard/DashboardActions.js +4 -3
  33. data/webpack/ForemanInventoryUpload/Components/Dashboard/DashboardSelectors.js +1 -1
  34. data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardActions.test.js +2 -3
  35. data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardIntegration.test.js +1 -1
  36. data/webpack/ForemanInventoryUpload/Components/Dashboard/__tests__/DashboardSelectors.test.js +3 -2
  37. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/Components/ClearButton/ClearButton.js +26 -0
  38. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/Components/ClearButton/index.js +1 -0
  39. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.fixtures.js +2 -0
  40. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +39 -0
  41. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilterActions.js +16 -0
  42. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilterConstants.js +3 -0
  43. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilterReducer.js +36 -0
  44. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilterSelectors.js +7 -0
  45. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilter.test.js +14 -0
  46. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterActions.test.js +14 -0
  47. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterReducer.test.js +35 -0
  48. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterSelectors.test.js +21 -0
  49. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilter.test.js.snap +25 -0
  50. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterActions.test.js.snap +17 -0
  51. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterReducer.test.js.snap +25 -0
  52. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterSelectors.test.js.snap +9 -0
  53. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/integration.test.js.snap +31 -0
  54. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/integration.test.js +18 -0
  55. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/index.js +17 -0
  56. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/inventoryFilter.scss +28 -0
  57. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js +12 -3
  58. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageHeader.test.js.snap +11 -2
  59. data/webpack/ForemanInventoryUpload/Components/PageHeader/pageHeader.scss +3 -0
  60. data/webpack/ForemanInventoryUpload/ForemanInventoryConstants.js +3 -0
  61. data/webpack/ForemanInventoryUpload/ForemanInventoryHelpers.js +4 -0
  62. data/webpack/ForemanInventoryUpload/ForemanInventoryUpload.js +16 -8
  63. data/webpack/ForemanInventoryUpload/ForemanInventoryUploadReducers.js +4 -4
  64. data/webpack/ForemanInventoryUpload/__tests__/ForemanInventoryHelpers.test.js +9 -0
  65. data/webpack/ForemanInventoryUpload/{ForemanInventoryUpload.test.js → __tests__/ForemanInventoryUpload.test.js} +1 -1
  66. data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryHelpers.test.js.snap +3 -0
  67. data/webpack/ForemanInventoryUpload/{__snapshots__ → __tests__/__snapshots__}/ForemanInventoryUpload.test.js.snap +0 -0
  68. data/webpack/ForemanRhCloudHelpers.js +6 -0
  69. data/webpack/ForemanRhCloudReducers.js +8 -0
  70. data/webpack/ForemanRhCloudSelectors.js +3 -0
  71. data/webpack/ForemanRhCloudTestHelpers.js +5 -0
  72. data/webpack/__mocks__/foremanReact/components/Layout/LayoutConstants.js +1 -0
  73. data/webpack/__tests__/ForemanRhCloudHelpers.test.js +11 -0
  74. data/webpack/__tests__/ForemanRhCloudSelectors.test.js +17 -0
  75. data/webpack/__tests__/ForemanRhCloudTestHelpers.test.js +10 -0
  76. data/webpack/__tests__/__snapshots__/ForemanRhCloudHelpers.test.js.snap +3 -0
  77. data/webpack/__tests__/__snapshots__/ForemanRhCloudSelectors.test.js.snap +15 -0
  78. data/webpack/__tests__/__snapshots__/ForemanRhCloudTestHelpers.test.js.snap +11 -0
  79. data/webpack/index.js +1 -1
  80. metadata +49 -9
  81. data/app/controllers/foreman_inventory_upload/react_controller.rb +0 -7
  82. data/test/unit/slice_generator_test.rb.orig +0 -280
  83. data/webpack/ForemanInventoryUpload/ForemanInventoryUploadSelectors.js +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f497849e8c31b5ca95c689315cd88222097b769c1cf41d9f3ebf89f9cd64febf
4
- data.tar.gz: deca6935796bd48f87e1bd6820deb732dc589dd6704fbd923270847be3d46984
3
+ metadata.gz: a9b4163dafd6baf15a6b8ffc04de58d1b0316114838e06ef3c3d28f043442a6c
4
+ data.tar.gz: 9c8bf6874697a56d76e696397cfc11ed0f3f1379716d5b91bebc54fdc4be98a0
5
5
  SHA512:
6
- metadata.gz: 4c0407bf3aa9d3ce7d3abc86ed6c82182024a68f7b370ba4b406d19924697a8af5c404bf4e361e638821f98a63cc81867c46d8aa6d3af9a8da0c774c33829b14
7
- data.tar.gz: 5f4de6af57144fa3e22f10ea1d25269fe309a268bb71b8b677cfcd606f1a507fec9b02ce744e7f184fe74f56b95ed7b6b9c5110d56f0e495d217afb573b6e3cb
6
+ metadata.gz: 56d9d668982202c78267c8b3d2425a6b3f3695be21fe3bf993710990c0811438b7bf938298e5a5421a40374dbb862d48538811388d851621bb4dbba8a7dfa396
7
+ data.tar.gz: e725d4ff38d466f6c1713822108ed9d04e08946f57fbd27032977b0ef7f4278c414d7d1c418f517a6d25b27b0e2131030ae8ba376ab27ac365729b9c60737f41
@@ -1,12 +1,8 @@
1
1
  module ForemanInventoryUpload
2
2
  class AccountsController < ::ApplicationController
3
- # override default "welcome screen behavior, since we don't have a model"
4
- def welcome
5
- true
6
- end
7
-
8
3
  def index
9
- labels = Organization.all.pluck(:id, :name)
4
+ organizations = User.current.my_organizations
5
+ labels = organizations.pluck(:id, :name)
10
6
 
11
7
  accounts = Hash[
12
8
  labels.map do |id, label|
@@ -0,0 +1,8 @@
1
+ module ForemanRhCloud
2
+ class ReactController < ::ApplicationController
3
+ layout "foreman_rh_cloud/application"
4
+
5
+ def inventory_upload
6
+ end
7
+ end
8
+ end
@@ -4,6 +4,7 @@ class Setting::RhCloud < Setting
4
4
  return unless super
5
5
  [
6
6
  set('allow_auto_inventory_upload', N_('Allow automatic upload of the host inventory to the Red Hat cloud'), true),
7
+ set('obfuscate_inventory_hostnames', N_('Obfuscate host names sent to Red Hat cloud'), false),
7
8
  ]
8
9
  end
9
10
 
@@ -0,0 +1 @@
1
+ <%= mount_react_component("ForemanInventoryUpload", '#ForemanRhCloudReactRoot') %>
@@ -10,7 +10,7 @@
10
10
  <%= notifications %>
11
11
  <div id="organization-id" data-id="<%= Organization.current.id if Organization.current %>" ></div>
12
12
  <div id="user-id" data-id="<%= User.current.id if User.current %>" ></div>
13
- <div id="ForemanInventoryUploadReactRoot"></div>
13
+ <div id="ForemanRhCloudReactRoot"></div>
14
+ <%= yield %>
14
15
  <% end %>
15
16
  <%= render file: "layouts/base" %>
16
- <%= mount_react_component('ForemanInventoryUpload', '#ForemanInventoryUploadReactRoot') %>
@@ -1,6 +1,5 @@
1
1
  Rails.application.routes.draw do
2
2
  namespace :foreman_inventory_upload do
3
- get 'index', to: 'react#index'
4
3
  get ':organization_id/reports/last', to: 'reports#last', constraints: { organization_id: %r{[^\/]+} }
5
4
  post ':organization_id/reports', to: 'reports#generate', constraints: { organization_id: %r{[^\/]+} }
6
5
  get ':organization_id/uploads/last', to: 'uploads#last', constraints: { organization_id: %r{[^\/]+} }
@@ -8,4 +7,8 @@ Rails.application.routes.draw do
8
7
  get 'accounts', to: 'accounts#index'
9
8
  post 'auto_upload', to: 'uploads#auto_upload'
10
9
  end
10
+
11
+ namespace :foreman_rh_cloud do
12
+ get 'inventory_upload', to: 'react#inventory_upload'
13
+ end
11
14
  end
@@ -3,6 +3,11 @@ module ForemanInventoryUpload
3
3
  module FactHelpers
4
4
  extend ActiveSupport::Concern
5
5
 
6
+ CLOUD_AMAZON = 'aws'
7
+ CLOUD_GOOGLE = 'google'
8
+ CLOUD_AZURE = 'azure'
9
+ CLOUD_ALIBABA = 'alibaba'
10
+
6
11
  def fact_value(host, fact_name)
7
12
  value_record = host.fact_values.find do |fact_value|
8
13
  fact_value.fact_name_id == ForemanInventoryUpload::Generators::Queries.fact_names[fact_name]
@@ -26,6 +31,44 @@ module ForemanInventoryUpload
26
31
  @organization_golden_tickets ||= {}
27
32
  @organization_golden_tickets[organization.id] ||= result
28
33
  end
34
+
35
+ def cloud_provider(host)
36
+ bios_version = fact_value(host, 'dmi::bios::version')
37
+
38
+ if bios_version
39
+ return CLOUD_AMAZON if bios_version.downcase['amazon']
40
+ return CLOUD_GOOGLE if bios_version.downcase['google']
41
+ end
42
+
43
+ chassis_asset_tag = fact_value(host, 'dmi::chassis::asset_tag')
44
+ return CLOUD_AZURE if chassis_asset_tag && chassis_asset_tag['7783-7084-3265-9085-8269-3286-77']
45
+
46
+ system_manufacturer = fact_value(host, 'dmi::system::manufacturer')
47
+ return CLOUD_ALIBABA if system_manufacturer && system_manufacturer.downcase['alibaba cloud']
48
+
49
+ product_name = fact_value(host, 'dmi::system::product_name')
50
+ return CLOUD_ALIBABA if product_name && product_name.downcase['alibaba cloud ecs']
51
+
52
+ nil
53
+ end
54
+
55
+ def obfuscate_hostname?(host)
56
+ insights_client_setting = fact_value(host, 'insights_client::obfuscate_hostname_enabled')
57
+ insights_client_setting = ActiveModel::Type::Boolean.new.cast(insights_client_setting)
58
+ return insights_client_setting unless insights_client_setting.nil?
59
+
60
+ Setting[:obfuscate_inventory_hostnames]
61
+ end
62
+
63
+ def fqdn(host)
64
+ return host.fqdn unless obfuscate_hostname?(host)
65
+
66
+ fact_value(host, 'insights_client::hostname') || obfuscate_fqdn(host.fqdn)
67
+ end
68
+
69
+ def obfuscate_fqdn(fqdn)
70
+ Base64.urlsafe_encode64(Digest::SHA1.digest(fqdn), padding: false)
71
+ end
29
72
  end
30
73
  end
31
74
  end
@@ -20,6 +20,11 @@ module ForemanInventoryUpload
20
20
  'distribution::version',
21
21
  'distribution::id',
22
22
  'virt::is_guest',
23
+ 'dmi::system::manufacturer',
24
+ 'dmi::system::product_name',
25
+ 'dmi::chassis::asset_tag',
26
+ 'insights_client::obfuscate_hostname_enabled',
27
+ 'insights_client::hostname',
23
28
  ]).pluck(:name, :id)
24
29
  ]
25
30
  end
@@ -39,7 +39,7 @@ module ForemanInventoryUpload
39
39
 
40
40
  def report_host(host)
41
41
  @stream.object do
42
- @stream.simple_field('fqdn', host.fqdn)
42
+ @stream.simple_field('fqdn', fqdn(host))
43
43
  @stream.simple_field('account', account_id(host.organization).to_s)
44
44
  @stream.simple_field('subscription_manager_id', host.subscription_facet&.uuid)
45
45
  @stream.simple_field('satellite_id', host.subscription_facet&.uuid)
@@ -126,6 +126,7 @@ module ForemanInventoryUpload
126
126
  'infrastructure_type',
127
127
  ActiveModel::Type::Boolean.new.cast(fact_value(host, 'virt::is_guest')) ? 'virtual' : 'physical'
128
128
  )
129
+ @stream.simple_field('cloud_provider', cloud_provider(host))
129
130
  unless (installed_products = host.subscription_facet&.installed_products).empty?
130
131
  @stream.array_field('installed_products') do
131
132
  @stream.raw(installed_products.map do |product|
@@ -30,15 +30,27 @@ module ForemanRhCloud
30
30
 
31
31
  # Add permissions
32
32
  security_block :foreman_rh_cloud do
33
- permission :view_foreman_rh_cloud, :'foreman_rh_cloud/reports' => [:last]
33
+ permission(:generate_foreman_rh_cloud, :'foreman_inventory_upload/reports' => [:generate])
34
+ permission(:view_foreman_rh_cloud,
35
+ 'foreman_inventory_upload/accounts': [:index],
36
+ 'foreman_inventory_upload/reports': [:last],
37
+ 'foreman_inventory_upload/uploads': [:auto_upload, :download_file, :last],
38
+ 'foreman_rh_cloud/react': [:inventory_upload]
39
+ )
34
40
  end
35
41
 
36
- # Add a new role called 'Discovery' if it doesn't exist
37
- role 'ForemanRhCloud', [:view_foreman_rh_cloud]
42
+ plugin_permissions = [:view_foreman_rh_cloud, :generate_foreman_rh_cloud]
43
+
44
+ role 'ForemanRhCloud', plugin_permissions, 'Role granting permissions to view the hosts inventory,
45
+ generate a report, upload it to the cloud and download it locally'
46
+
47
+ add_permissions_to_default_roles Role::ORG_ADMIN => plugin_permissions,
48
+ Role::MANAGER => plugin_permissions,
49
+ Role::SYSTEM_ADMIN => plugin_permissions
38
50
 
39
51
  # Adding a sub menu after hosts menu
40
52
  sub_menu :top_menu, :foreman_rh_cloud, :caption => N_('RH Cloud'), :icon => 'fa fa-cloud-upload' do
41
- menu :top_menu, :level1, :caption => N_('Inventory Upload'), :url_hash => { controller: :'foreman_inventory_upload/react', :action => :index}
53
+ menu :top_menu, :level1, :caption => N_('Inventory Upload'), :url_hash => { controller: :'foreman_rh_cloud/react', :action => :inventory_upload}
42
54
  end
43
55
  end
44
56
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '2.0.6'.freeze
2
+ VERSION = '2.0.7'.freeze
3
3
  end
@@ -38,6 +38,11 @@ class ReportGeneratorTest < ActiveSupport::TestCase
38
38
  'distribution::version',
39
39
  'distribution::id',
40
40
  'virt::is_guest',
41
+ 'dmi::system::manufacturer',
42
+ 'dmi::system::product_name',
43
+ 'dmi::chassis::asset_tag',
44
+ 'insights_client::obfuscate_hostname_enabled',
45
+ 'insights_client::hostname',
41
46
  ]
42
47
  end
43
48
 
@@ -63,6 +68,58 @@ class ReportGeneratorTest < ActiveSupport::TestCase
63
68
  assert_equal 1, generator.hosts_count
64
69
  end
65
70
 
71
+ test 'obfuscates fqdn when instructed by insights-client' do
72
+ FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_hostname_enabled'], value: 'true', host: @host)
73
+ FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::hostname'], value: 'obfuscated_name', host: @host)
74
+
75
+ batch = Host.where(id: @host.id).in_batches.first
76
+ generator = create_generator(batch)
77
+
78
+ json_str = generator.render
79
+ actual = JSON.parse(json_str.join("\n"))
80
+
81
+ assert_equal 'slice_123', actual['report_slice_id']
82
+ assert_not_nil(actual_host = actual['hosts'].first)
83
+ assert_equal 'obfuscated_name', actual_host['fqdn']
84
+ assert_equal '1234', actual_host['account']
85
+ assert_equal 1, generator.hosts_count
86
+ end
87
+
88
+ test 'obfuscates fqdn when setting set' do
89
+ FactoryBot.create(:setting, :name => 'obfuscate_inventory_hostnames', :value => true)
90
+
91
+ batch = Host.where(id: @host.id).in_batches.first
92
+ generator = create_generator(batch)
93
+
94
+ json_str = generator.render
95
+ actual = JSON.parse(json_str.join("\n"))
96
+
97
+ obfuscated_fqdn = Base64.urlsafe_encode64(Digest::SHA1.digest(@host.fqdn), padding: false)
98
+
99
+ assert_equal 'slice_123', actual['report_slice_id']
100
+ assert_not_nil(actual_host = actual['hosts'].first)
101
+ assert_equal obfuscated_fqdn, actual_host['fqdn']
102
+ assert_equal '1234', actual_host['account']
103
+ assert_equal 1, generator.hosts_count
104
+ end
105
+
106
+ test 'does not obfuscate fqdn when insights-client sets to false' do
107
+ FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_hostname_enabled'], value: 'false', host: @host)
108
+ FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::hostname'], value: 'obfuscated_name', host: @host)
109
+
110
+ batch = Host.where(id: @host.id).in_batches.first
111
+ generator = create_generator(batch)
112
+
113
+ json_str = generator.render
114
+ actual = JSON.parse(json_str.join("\n"))
115
+
116
+ assert_equal 'slice_123', actual['report_slice_id']
117
+ assert_not_nil(actual_host = actual['hosts'].first)
118
+ assert_equal @host.fqdn, actual_host['fqdn']
119
+ assert_equal '1234', actual_host['account']
120
+ assert_equal 1, generator.hosts_count
121
+ end
122
+
66
123
  test 'generates a report with satellite facts' do
67
124
  Foreman.expects(:instance_id).twice.returns('satellite-id')
68
125
  batch = Host.where(id: @host.id).in_batches.first
@@ -260,6 +317,81 @@ class ReportGeneratorTest < ActiveSupport::TestCase
260
317
  assert_equal 'physical', actual_profile['infrastructure_type']
261
318
  end
262
319
 
320
+ test 'Identifies Amazon cloud provider' do
321
+ FactoryBot.create(:fact_value, fact_name: fact_names['dmi::bios::version'], value: 'Test Amazon version', host: @host)
322
+
323
+ batch = Host.where(id: @host.id).in_batches.first
324
+ generator = create_generator(batch)
325
+
326
+ json_str = generator.render
327
+ actual = JSON.parse(json_str.join("\n"))
328
+
329
+ assert_equal 'slice_123', actual['report_slice_id']
330
+ assert_not_nil(actual_host = actual['hosts'].first)
331
+ assert_not_nil(actual_profile = actual_host['system_profile'])
332
+ assert_equal 'aws', actual_profile['cloud_provider']
333
+ end
334
+
335
+ test 'Identifies Google cloud provider' do
336
+ FactoryBot.create(:fact_value, fact_name: fact_names['dmi::bios::version'], value: 'Test Google version', host: @host)
337
+
338
+ batch = Host.where(id: @host.id).in_batches.first
339
+ generator = create_generator(batch)
340
+
341
+ json_str = generator.render
342
+ actual = JSON.parse(json_str.join("\n"))
343
+
344
+ assert_equal 'slice_123', actual['report_slice_id']
345
+ assert_not_nil(actual_host = actual['hosts'].first)
346
+ assert_not_nil(actual_profile = actual_host['system_profile'])
347
+ assert_equal 'google', actual_profile['cloud_provider']
348
+ end
349
+
350
+ test 'Identifies Azure cloud provider' do
351
+ FactoryBot.create(:fact_value, fact_name: fact_names['dmi::chassis::asset_tag'], value: '7783-7084-3265-9085-8269-3286-77', host: @host)
352
+
353
+ batch = Host.where(id: @host.id).in_batches.first
354
+ generator = create_generator(batch)
355
+
356
+ json_str = generator.render
357
+ actual = JSON.parse(json_str.join("\n"))
358
+
359
+ assert_equal 'slice_123', actual['report_slice_id']
360
+ assert_not_nil(actual_host = actual['hosts'].first)
361
+ assert_not_nil(actual_profile = actual_host['system_profile'])
362
+ assert_equal 'azure', actual_profile['cloud_provider']
363
+ end
364
+
365
+ test 'Identifies Alibaba cloud provider via manufacturer' do
366
+ FactoryBot.create(:fact_value, fact_name: fact_names['dmi::system::manufacturer'], value: 'Test Alibaba Cloud version', host: @host)
367
+
368
+ batch = Host.where(id: @host.id).in_batches.first
369
+ generator = create_generator(batch)
370
+
371
+ json_str = generator.render
372
+ actual = JSON.parse(json_str.join("\n"))
373
+
374
+ assert_equal 'slice_123', actual['report_slice_id']
375
+ assert_not_nil(actual_host = actual['hosts'].first)
376
+ assert_not_nil(actual_profile = actual_host['system_profile'])
377
+ assert_equal 'alibaba', actual_profile['cloud_provider']
378
+ end
379
+
380
+ test 'Identifies Alibaba cloud provider via product name' do
381
+ FactoryBot.create(:fact_value, fact_name: fact_names['dmi::system::product_name'], value: 'Test Alibaba Cloud ECS product', host: @host)
382
+
383
+ batch = Host.where(id: @host.id).in_batches.first
384
+ generator = create_generator(batch)
385
+
386
+ json_str = generator.render
387
+ actual = JSON.parse(json_str.join("\n"))
388
+
389
+ assert_equal 'slice_123', actual['report_slice_id']
390
+ assert_not_nil(actual_host = actual['hosts'].first)
391
+ assert_not_nil(actual_profile = actual_host['system_profile'])
392
+ assert_equal 'alibaba', actual_profile['cloud_provider']
393
+ end
394
+
263
395
  private
264
396
 
265
397
  def create_generator(batch, name = 'slice_123')
@@ -1,6 +1,6 @@
1
1
  import { noop } from 'patternfly-react';
2
2
 
3
- export const API_SUCCESS_RESPONSE = {
3
+ export const accounts = {
4
4
  Account1: {
5
5
  label: 'test_org1',
6
6
  upload_report_status: 'running',
@@ -18,7 +18,9 @@ export const API_SUCCESS_RESPONSE = {
18
18
  },
19
19
  };
20
20
 
21
- export const accounts = API_SUCCESS_RESPONSE;
21
+ export const accountIDs = Object.keys(accounts);
22
+
23
+ export const API_SUCCESS_RESPONSE = accounts;
22
24
 
23
25
  export const pollingProcessID = 0;
24
26
 
@@ -30,6 +32,8 @@ export const processStatusName = 'upload_report_status';
30
32
 
31
33
  export const autoUploadEnabled = true;
32
34
 
35
+ export const filterTerm = 'some_filter';
36
+
33
37
  export const props = {
34
38
  accounts,
35
39
  fetchAccountsStatus: noop,
@@ -4,6 +4,8 @@ import PropTypes from 'prop-types';
4
4
  import ListItem from './Components/ListItem';
5
5
  import EmptyState from './Components/EmptyState';
6
6
  import ErrorState from './Components/ErrorState';
7
+ import EmptyResults from './Components/EmptyResults';
8
+ import { filterAccounts } from './AccountListHelper';
7
9
  import './accountList.scss';
8
10
 
9
11
  class AccountList extends Component {
@@ -20,8 +22,9 @@ class AccountList extends Component {
20
22
  }
21
23
 
22
24
  render() {
23
- const { accounts, error } = this.props;
25
+ const { accounts, error, filterTerm } = this.props;
24
26
  const accountIds = Object.keys(accounts);
27
+ const filteredAccountIds = filterAccounts(accounts, accountIds, filterTerm);
25
28
 
26
29
  if (error) {
27
30
  return <ErrorState error={error} />;
@@ -30,16 +33,14 @@ class AccountList extends Component {
30
33
  if (accountIds.length === 0) {
31
34
  return <EmptyState />;
32
35
  }
33
- const items = accountIds.map((accountID, index) => {
36
+
37
+ if (filteredAccountIds.length === 0) {
38
+ return <EmptyResults />;
39
+ }
40
+
41
+ const items = filteredAccountIds.map((accountID, index) => {
34
42
  const account = accounts[accountID];
35
- return (
36
- <ListItem
37
- key={index}
38
- accountID={accountID}
39
- account={account}
40
- initExpanded={index === 0}
41
- />
42
- );
43
+ return <ListItem key={index} accountID={accountID} account={account} />;
43
44
  });
44
45
  return <ListView className="account_list">{items}</ListView>;
45
46
  }
@@ -56,6 +57,7 @@ AccountList.propTypes = {
56
57
  }),
57
58
  accounts: PropTypes.object,
58
59
  error: PropTypes.string,
60
+ filterTerm: PropTypes.string,
59
61
  };
60
62
 
61
63
  AccountList.defaultProps = {
@@ -69,6 +71,7 @@ AccountList.defaultProps = {
69
71
  },
70
72
  accounts: {},
71
73
  error: '',
74
+ filterTerm: null,
72
75
  };
73
76
 
74
77
  export default AccountList;
@@ -1,4 +1,5 @@
1
1
  import API from 'foremanReact/API';
2
+ import { inventoryUrl } from '../../ForemanInventoryHelpers';
2
3
  import {
3
4
  INVENTORY_ACCOUNT_STATUS_POLLING,
4
5
  INVENTORY_ACCOUNT_STATUS_POLLING_ERROR,
@@ -11,7 +12,7 @@ export const fetchAccountsStatus = () => async dispatch => {
11
12
  try {
12
13
  const {
13
14
  data: { accounts, autoUploadEnabled },
14
- } = await API.get('accounts');
15
+ } = await API.get(inventoryUrl('accounts'));
15
16
  dispatch({
16
17
  type: INVENTORY_ACCOUNT_STATUS_POLLING,
17
18
  payload: {
@@ -55,7 +56,7 @@ export const restartProcess = (accountID, activeTab) => dispatch => {
55
56
  processStatusName = 'generate_report_status';
56
57
  }
57
58
 
58
- API.post(`${accountID}/${processController}`);
59
+ API.post(inventoryUrl(`${accountID}/${processController}`));
59
60
  dispatch({
60
61
  type: INVENTORY_PROCESS_RESTART,
61
62
  payload: {