foreman_rh_cloud 0.9.8 → 0.9.13

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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -0
  3. data/app/controllers/foreman_inventory_upload/accounts_controller.rb +3 -0
  4. data/app/controllers/foreman_inventory_upload/tasks_controller.rb +25 -0
  5. data/app/controllers/foreman_inventory_upload/uploads_controller.rb +18 -0
  6. data/app/controllers/insights_cloud/hits_controller.rb +17 -0
  7. data/app/controllers/insights_cloud/settings_controller.rb +24 -0
  8. data/app/controllers/insights_cloud/tasks_controller.rb +1 -2
  9. data/app/helpers/foreman_inventory_upload_host_helper.rb +10 -2
  10. data/app/models/concerns/rh_cloud_host.rb +15 -0
  11. data/app/models/insights_facet.rb +5 -1
  12. data/app/models/insights_hit.rb +1 -1
  13. data/app/models/inventory_sync/inventory_status.rb +30 -0
  14. data/app/models/setting/rh_cloud.rb +4 -1
  15. data/app/overrides/hosts_list.rb +1 -1
  16. data/app/services/foreman_rh_cloud/cloud_auth.rb +28 -0
  17. data/app/views/foreman_rh_cloud/react/insights_cloud.html.erb +6 -1
  18. data/app/views/foreman_rh_cloud/react/inventory_upload.html.erb +1 -1
  19. data/app/views/hosts/_insights_tab.html.erb +15 -0
  20. data/config/routes.rb +6 -0
  21. data/db/migrate/20200727111529_add_uuid_column_to_insights_facets.foreman_rh_cloud.rb +5 -0
  22. data/db/migrate/20201007115752_add_hits_count_to_insights_facets_table.foreman_rh_cloud.rb +5 -0
  23. data/db/migrate/20201007121540_setup_hits_count_cache.foreman_rh_cloud.rb +10 -0
  24. data/lib/foreman_inventory_upload.rb +4 -0
  25. data/lib/foreman_inventory_upload/async/generate_report_job.rb +1 -1
  26. data/lib/foreman_inventory_upload/async/shell_process.rb +15 -9
  27. data/lib/foreman_inventory_upload/async/upload_report_job.rb +21 -9
  28. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +36 -1
  29. data/lib/foreman_inventory_upload/generators/json_stream.rb +17 -2
  30. data/lib/foreman_inventory_upload/generators/metadata.rb +3 -0
  31. data/lib/foreman_inventory_upload/generators/queries.rb +4 -4
  32. data/lib/foreman_inventory_upload/generators/slice.rb +62 -34
  33. data/lib/foreman_rh_cloud.rb +67 -0
  34. data/lib/foreman_rh_cloud/engine.rb +20 -3
  35. data/lib/foreman_rh_cloud/version.rb +1 -1
  36. data/lib/insights_cloud.rb +8 -8
  37. data/lib/insights_cloud/async/insights_full_sync.rb +24 -32
  38. data/lib/insights_cloud/async/insights_scheduled_sync.rb +23 -0
  39. data/lib/inventory_sync/async/host_result.rb +50 -0
  40. data/lib/inventory_sync/async/inventory_full_sync.rb +80 -0
  41. data/lib/tasks/insights.rake +15 -0
  42. data/lib/tasks/rh_cloud_inventory.rake +37 -0
  43. data/package.json +3 -1
  44. data/test/controllers/insights_sync/settings_controller_test.rb +30 -0
  45. data/test/factories/insights_factories.rb +31 -0
  46. data/test/jobs/insights_full_sync_test.rb +33 -1
  47. data/test/jobs/inventory_full_sync_test.rb +91 -0
  48. data/test/jobs/upload_report_job_test.rb +34 -0
  49. data/test/unit/fact_helpers_test.rb +22 -0
  50. data/test/unit/insights_facet_test.rb +23 -0
  51. data/test/unit/metadata_generator_test.rb +2 -0
  52. data/test/unit/rh_cloud_http_proxy_test.rb +52 -0
  53. data/test/unit/slice_generator_test.rb +173 -11
  54. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.fixtures.js +16 -1
  55. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListActions.js +22 -17
  56. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListReducer.js +18 -0
  57. data/webpack/ForemanInventoryUpload/Components/AccountList/AccountListSelectors.js +8 -0
  58. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListActions.test.js +7 -0
  59. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListReducer.test.js +12 -6
  60. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListSelectors.test.js +9 -0
  61. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListActions.test.js.snap +20 -0
  62. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListReducer.test.js.snap +12 -0
  63. data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListSelectors.test.js.snap +6 -0
  64. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcher.fixtures.js +2 -0
  65. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcherActions.js +10 -11
  66. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/AutoUploadSwitcherConstants.js +0 -1
  67. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/AutoUploadSwitcherActions.test.js +12 -2
  68. data/webpack/ForemanInventoryUpload/Components/AutoUploadSwitcher/__tests__/__snapshots__/AutoUploadSwitcherActions.test.js.snap +17 -0
  69. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/ExcludePackagesSwitcher.fixtures.js +1 -0
  70. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/ExcludePackagesSwitcher.js +30 -0
  71. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/ExcludePackagesSwitcherActions.js +29 -0
  72. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/ExcludePackagesSwitcherConstants.js +1 -0
  73. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/ExcludePackagesSwitcher.test.js +13 -0
  74. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/ExcludePackagesSwitcherActions.test.js +21 -0
  75. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/__snapshots__/ExcludePackagesSwitcher.test.js.snap +38 -0
  76. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/__snapshots__/ExcludePackagesSwitcherActions.test.js.snap +31 -0
  77. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/__snapshots__/integration.test.js.snap +41 -0
  78. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/__tests__/integration.test.js +38 -0
  79. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/excludePackagesSwitcher.scss +3 -0
  80. data/webpack/ForemanInventoryUpload/Components/ExcludePackagesSwitcher/index.js +20 -0
  81. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/FullScreenModal.js +5 -1
  82. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/__tests__/__snapshots__/FullScreenModal.test.js.snap +1 -0
  83. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/fullScreenModal.scss +15 -13
  84. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/HostObfuscationSwitcher.fixtures.js +2 -1
  85. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/HostObfuscationSwitcher.js +1 -0
  86. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/HostObfuscationSwitcher.scss +3 -0
  87. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/HostObfuscationSwitcherActions.js +10 -11
  88. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/HostObfuscationSwitcherConstants.js +0 -2
  89. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/__tests__/HostObfuscationSwitcherActions.test.js +12 -2
  90. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/__tests__/__snapshots__/HostObfuscationSwitcherActions.test.js.snap +18 -1
  91. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/integration.test.js.snap +9 -0
  92. data/webpack/ForemanInventoryUpload/Components/InventorySettings/InventorySettings.js +4 -0
  93. data/webpack/ForemanInventoryUpload/Components/InventorySettings/__tests__/__snapshots__/InventorySettings.test.js.snap +2 -0
  94. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/IpsObfuscationSwitcher.fixtures.js +1 -0
  95. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/IpsObfuscationSwitcher.js +29 -0
  96. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/IpsObfuscationSwitcherActions.js +29 -0
  97. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/IpsObfuscationSwitcherConstants.js +1 -0
  98. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/__tests__/IpsObfuscationSwitcher.test.js +13 -0
  99. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/__tests__/IpsObfuscationSwitcherActions.test.js +21 -0
  100. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/__tests__/__snapshots__/IpsObfuscationSwitcher.test.js.snap +38 -0
  101. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/__tests__/__snapshots__/IpsObfuscationSwitcherActions.test.js.snap +31 -0
  102. data/webpack/ForemanInventoryUpload/Components/IpsObfuscationSwitcher/index.js +20 -0
  103. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js +1 -1
  104. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageHeader.test.js.snap +3 -3
  105. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/DocsButton/DocsButton.js +1 -0
  106. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/DocsButton/__tests__/__snapshots__/DocsButton.test.js.snap +1 -0
  107. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/HistoryButton/HistoryButton.js +1 -0
  108. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/HistoryButton/__tests__/__snapshots__/HistoryButton.test.js.snap +1 -0
  109. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +2 -2
  110. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +2 -2
  111. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +58 -0
  112. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonActions.js +57 -0
  113. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonConstants.js +3 -0
  114. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonReducer.js +36 -0
  115. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonSelectors.js +13 -0
  116. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButton.test.js +13 -0
  117. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButtonActions.test.js +31 -0
  118. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButtonFixtures.js +9 -0
  119. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButtonReducer.test.js +26 -0
  120. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButtonSelectors.test.js +36 -0
  121. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +26 -0
  122. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButtonActions.test.js.snap +98 -0
  123. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButtonReducer.test.js.snap +18 -0
  124. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButtonSelectors.test.js.snap +18 -0
  125. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/Modal.js +63 -0
  126. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/Toast.js +41 -0
  127. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/modal.scss +20 -0
  128. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/index.js +22 -0
  129. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/ToolbarButtons.js +2 -0
  130. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/__tests__/__snapshots__/ToolbarButtons.test.js.snap +1 -0
  131. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/toolbarButtons.scss +6 -1
  132. data/webpack/ForemanInventoryUpload/Components/StatusChart/StatusChart.js +1 -1
  133. data/webpack/ForemanInventoryUpload/Components/StatusChart/__tests__/__snapshots__/StatusChart.test.js.snap +1 -1
  134. data/webpack/ForemanInventoryUpload/Components/TabContainer/tabContainer.scss +1 -1
  135. data/webpack/ForemanInventoryUpload/Components/TabHeader/TabHeader.js +6 -1
  136. data/webpack/ForemanInventoryUpload/Components/Terminal/Terminal.js +2 -4
  137. data/webpack/ForemanInventoryUpload/ForemanInventoryConstants.js +3 -1
  138. data/webpack/ForemanInventoryUpload/ForemanInventoryHelpers.js +8 -0
  139. data/webpack/ForemanInventoryUpload/ForemanInventoryUploadReducers.js +2 -0
  140. data/webpack/ForemanRhCloudPages.js +9 -0
  141. data/webpack/ForemanRhCloudReducers.js +2 -0
  142. data/webpack/ForemanRhCloudSelectors.js +5 -0
  143. data/webpack/ForemanRhCloudTestHelpers.js +17 -3
  144. data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js +33 -0
  145. data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsActions.js +57 -0
  146. data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsConstants.js +4 -0
  147. data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsReducer.js +24 -0
  148. data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsSelectors.js +6 -0
  149. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettings.test.js +18 -0
  150. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsActions.test.js +62 -0
  151. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsReducer.test.js +33 -0
  152. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsSelectors.test.js +21 -0
  153. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettings.test.js.snap +15 -0
  154. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsActions.test.js.snap +65 -0
  155. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsReducer.test.js.snap +19 -0
  156. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsSelectors.test.js.snap +9 -0
  157. data/webpack/InsightsCloudSync/Components/InsightsSettings/index.js +21 -0
  158. data/webpack/InsightsCloudSync/Components/InsightsSettings/insightsSettings.scss +16 -0
  159. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/InsightsSyncSwitcher.fixtures.js +1 -0
  160. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/InsightsSyncSwitcher.js +45 -0
  161. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/__tests__/InsightsSyncSwitcher.test.js +17 -0
  162. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/__tests__/__snapshots__/InsightsSyncSwitcher.test.js.snap +38 -0
  163. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/index.js +1 -0
  164. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/insightsSyncSwitcher.scss +3 -0
  165. data/webpack/InsightsCloudSync/InsightsCloudSync.js +38 -5
  166. data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +3 -0
  167. data/webpack/InsightsCloudSync/InsightsCloudSyncActions.js +10 -11
  168. data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +0 -2
  169. data/webpack/InsightsCloudSync/InsightsCloudSyncReducers.js +7 -2
  170. data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +49 -9
  171. data/webpack/InsightsCloudSync/index.js +2 -1
  172. data/webpack/InsightsHostDetailsTab/InsightsTab.js +64 -0
  173. data/webpack/InsightsHostDetailsTab/InsightsTab.scss +86 -0
  174. data/webpack/InsightsHostDetailsTab/InsightsTabActions.js +31 -0
  175. data/webpack/InsightsHostDetailsTab/InsightsTabConstants.js +2 -0
  176. data/webpack/InsightsHostDetailsTab/InsightsTabReducer.js +19 -0
  177. data/webpack/InsightsHostDetailsTab/InsightsTabSelectors.js +3 -0
  178. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTab.fixtures.js +25 -0
  179. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTab.test.js +13 -0
  180. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabActions.test.js +19 -0
  181. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabIntegration.test.js +17 -0
  182. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabReducer.test.js +26 -0
  183. data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabSelectors.test.js +13 -0
  184. data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTab.test.js.snap +30 -0
  185. data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabActions.test.js.snap +58 -0
  186. data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabReducer.test.js.snap +34 -0
  187. data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabSelectors.test.js.snap +20 -0
  188. data/webpack/InsightsHostDetailsTab/components/ListItem/ListItem.js +69 -0
  189. data/webpack/InsightsHostDetailsTab/components/ListItem/index.js +1 -0
  190. data/webpack/InsightsHostDetailsTab/index.js +20 -0
  191. data/webpack/__mocks__/foremanReact/constants.js +5 -0
  192. data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
  193. data/webpack/__tests__/ForemanRhCloudSelectors.test.js +4 -1
  194. data/webpack/__tests__/ForemanRhCloudTestHelpers.test.js +12 -2
  195. data/webpack/__tests__/__snapshots__/ForemanRhCloudSelectors.test.js.snap +10 -9
  196. data/webpack/__tests__/__snapshots__/ForemanRhCloudTestHelpers.test.js.snap +27 -2
  197. data/webpack/index.js +2 -12
  198. data/webpack/stories/decorators/withCardsDecorator.js +1 -1
  199. metadata +120 -12
  200. data/lib/tasks/generator.rake +0 -29
  201. data/webpack/ForemanInventoryUpload/Components/HostObfuscationSwitcher/hostObfuscationSwitcher.scss +0 -0
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  module ForemanInventoryUpload
2
4
  module Generators
3
5
  module FactHelpers
@@ -67,7 +69,40 @@ module ForemanInventoryUpload
67
69
  end
68
70
 
69
71
  def obfuscate_fqdn(fqdn)
70
- Digest::SHA1.hexdigest(fqdn)
72
+ "#{Digest::SHA1.hexdigest(fqdn)}.example.com"
73
+ end
74
+
75
+ def obfuscate_ips?(host)
76
+ insights_client_setting = fact_value(host, 'insights_client::obfuscate_ip_enabled')
77
+ insights_client_setting = ActiveModel::Type::Boolean.new.cast(insights_client_setting)
78
+ return insights_client_setting unless insights_client_setting.nil?
79
+
80
+ Setting[:obfuscate_inventory_ips]
81
+ end
82
+
83
+ def host_ips(host)
84
+ return obfuscated_ips(host) if obfuscate_ips?(host)
85
+
86
+ # return a pass through proxy hash in case no obfuscation needed
87
+ Hash.new { |h, k| k }
88
+ end
89
+
90
+ def obfuscated_ips(host)
91
+ insights_client_ips = JSON.parse(fact_value(host, 'insights_client::ips') || '[]')
92
+
93
+ obfuscated_ips = Hash[
94
+ insights_client_ips.map { |ip_record| [ip_record['original'], ip_record['obfuscated']] }
95
+ ]
96
+
97
+ obfuscated_ips.default_proc = proc do |hash, key|
98
+ hash[key] = obfuscate_ip(key, hash)
99
+ end
100
+
101
+ obfuscated_ips
102
+ end
103
+
104
+ def obfuscate_ip(ip, ips_dict)
105
+ "10.230.230.#{ips_dict.count + 1}"
71
106
  end
72
107
  end
73
108
  end
@@ -26,8 +26,13 @@ module ForemanInventoryUpload
26
26
  @out << string
27
27
  end
28
28
 
29
- def simple_field(name, value, last = false)
30
- @out << "\"#{name}\": #{stringify_value(value)}#{last ? '' : ','}" unless value.nil?
29
+ def simple_field(name, value, last = false, &block)
30
+ return if value.nil? || value.try(:empty?)
31
+ return if value.kind_of?(Array) && value.compact.empty?
32
+
33
+ block ||= ->(value) { value }
34
+
35
+ @out << "\"#{name}\": #{stringify_value(block.call(value))}#{last ? '' : ','}"
31
36
  end
32
37
 
33
38
  def array_field(name, last = false, &block)
@@ -36,6 +41,16 @@ module ForemanInventoryUpload
36
41
  @out << ',' unless last
37
42
  end
38
43
 
44
+ def string_array_value(name, value, last = false)
45
+ return if value.empty?
46
+
47
+ string_value = value.map { |v| stringify_value(v) }
48
+
49
+ array_field(name, last) do
50
+ raw(string_value.join(', '))
51
+ end
52
+ end
53
+
39
54
  def object_field(name, last = false, &block)
40
55
  @out << "\"#{name}\": "
41
56
  object(&block)
@@ -21,6 +21,9 @@ module ForemanInventoryUpload
21
21
  private
22
22
 
23
23
  def render_report(metadata)
24
+ metadata ||= {}
25
+ metadata['foreman_rh_cloud_version'] = ForemanRhCloud::VERSION
26
+
24
27
  @stream.object do
25
28
  @stream.simple_field('report_id', Foreman.uuid)
26
29
  @stream.simple_field('host_inventory_api_version', '1.0')
@@ -24,29 +24,29 @@ module ForemanInventoryUpload
24
24
  'dmi::system::product_name',
25
25
  'dmi::chassis::asset_tag',
26
26
  'insights_client::obfuscate_hostname_enabled',
27
+ 'insights_client::obfuscate_ip_enabled',
27
28
  'insights_client::hostname',
29
+ 'insights_client::ips',
28
30
  ]).pluck(:name, :id)
29
31
  ]
30
32
  end
31
33
 
32
34
  def self.for_slice(base)
33
- fact_values = FactValue.where(fact_name_id: fact_names.values)
34
35
  base
35
36
  .joins(:subscription_facet)
36
- .eager_load(:fact_values)
37
37
  .preload(
38
38
  :interfaces,
39
39
  :installed_packages,
40
40
  :content_facet,
41
41
  :host_statuses,
42
+ :inventory_upload_facts,
42
43
  subscription_facet: [:pools, :installed_products, :hypervisor_host]
43
44
  )
44
- .merge(fact_values)
45
45
  end
46
46
 
47
47
  def self.for_report(portal_user)
48
48
  org_ids = organizations_for_user(portal_user).pluck(:id)
49
- for_slice(Host.unscoped.where(organization_id: org_ids)).in_batches(of: 1_000)
49
+ for_org(org_ids)
50
50
  end
51
51
 
52
52
  def self.for_org(organization_id)
@@ -3,6 +3,8 @@ module ForemanInventoryUpload
3
3
  class Slice
4
4
  include FactHelpers
5
5
 
6
+ SATELLITE_NAMESPACE = 'satellite'
7
+
6
8
  attr_accessor :slice_id
7
9
  attr_reader :hosts_count
8
10
 
@@ -38,6 +40,7 @@ module ForemanInventoryUpload
38
40
  end
39
41
 
40
42
  def report_host(host)
43
+ host_ips_cache = host_ips(host)
41
44
  @stream.object do
42
45
  @stream.simple_field('fqdn', fqdn(host))
43
46
  @stream.simple_field('account', account_id(host.organization).to_s)
@@ -45,22 +48,14 @@ module ForemanInventoryUpload
45
48
  @stream.simple_field('satellite_id', host.subscription_facet&.uuid)
46
49
  @stream.simple_field('bios_uuid', fact_value(host, 'dmi::system::uuid'))
47
50
  @stream.simple_field('vm_uuid', fact_value(host, 'virt::uuid'))
48
- @stream.array_field('ip_addresses') do
49
- @stream.raw(host.interfaces.map do |nic|
50
- @stream.stringify_value(nic.ip) if nic.ip
51
- end.compact.join(', '))
52
- end
53
- @stream.array_field('mac_addresses') do
54
- @stream.raw(host.interfaces.map do |nic|
55
- @stream.stringify_value(nic.mac) if nic.mac
56
- end.compact.join(', '))
57
- end
51
+ report_ip_addresses(host, host_ips_cache)
52
+ report_mac_addresses(host)
58
53
  @stream.object_field('system_profile') do
59
- report_system_profile(host)
54
+ report_system_profile(host, host_ips_cache)
60
55
  end
61
56
  @stream.array_field('facts') do
62
57
  @stream.object do
63
- @stream.simple_field('namespace', 'satellite')
58
+ @stream.simple_field('namespace', SATELLITE_NAMESPACE)
64
59
  @stream.object_field('facts', :last) do
65
60
  report_satellite_facts(host)
66
61
  end
@@ -68,8 +63,15 @@ module ForemanInventoryUpload
68
63
  end
69
64
 
70
65
  @stream.array_field('tags', :last) do
71
- report_tag('satellite', 'satellite_instance_id', Foreman.instance_id) if Foreman.respond_to?(:instance_id)
72
- report_tag('satellite', 'organization_id', host.organization_id.to_s, :last)
66
+ report_satellite_tag('satellite_instance_id', Foreman.instance_id) if Foreman.respond_to?(:instance_id)
67
+ report_satellite_tag('lifecycle_environment', host.lifecycle_environment&.name)
68
+ report_satellite_tag('content_view', host.content_view&.name)
69
+ report_satellite_tag('activation_key', host.activation_keys) { |key| key.name }
70
+ report_satellite_tag('host_collection', host.host_collections) { |collection| collection.name }
71
+ report_satellite_tag('location', host.location.name)
72
+ report_satellite_tag('organization', host.organization.name)
73
+ report_satellite_tag('hostgroup', host.hostgroup&.name)
74
+ report_satellite_tag('organization_id', host.organization_id.to_s, :last)
73
75
  end
74
76
  end
75
77
  end
@@ -83,15 +85,27 @@ module ForemanInventoryUpload
83
85
  @stream.comma unless last
84
86
  end
85
87
 
86
- def report_system_profile(host)
87
- @stream.simple_field('number_of_cpus', fact_value(host, 'cpu::cpu(s)').to_i)
88
- @stream.simple_field('number_of_sockets', fact_value(host, 'cpu::cpu_socket(s)').to_i)
89
- @stream.simple_field('cores_per_socket', fact_value(host, 'cpu::core(s)_per_socket').to_i)
90
- @stream.simple_field('system_memory_bytes', kilobytes_to_bytes(fact_value(host, 'memory::memtotal').to_i))
88
+ def report_satellite_tag(key, value, last = nil)
89
+ return if value.nil?
90
+
91
+ array_value = Array(value)
92
+ last_index = array_value.count - 1
93
+
94
+ array_value.each_with_index do |value, index|
95
+ value = yield(value) if block_given?
96
+ report_tag(SATELLITE_NAMESPACE, key, value, last && index == last_index)
97
+ end
98
+ end
99
+
100
+ def report_system_profile(host, host_ips_cache)
101
+ @stream.simple_field('number_of_cpus', fact_value(host, 'cpu::cpu(s)')) { |v| v.to_i }
102
+ @stream.simple_field('number_of_sockets', fact_value(host, 'cpu::cpu_socket(s)')) { |v| v.to_i }
103
+ @stream.simple_field('cores_per_socket', fact_value(host, 'cpu::core(s)_per_socket')) { |v| v.to_i }
104
+ @stream.simple_field('system_memory_bytes', fact_value(host, 'memory::memtotal')) { |v| kilobytes_to_bytes(v.to_i) }
91
105
  @stream.array_field('network_interfaces') do
92
106
  @stream.raw(host.interfaces.map do |nic|
93
107
  {
94
- 'ipv4_addresses': [nic.ip].compact,
108
+ 'ipv4_addresses': [host_ips_cache[nic.ip]].compact,
95
109
  'ipv6_addresses': [nic.ip6].compact,
96
110
  'mtu': nic.try(:mtu),
97
111
  'mac_address': nic.mac,
@@ -110,18 +124,16 @@ module ForemanInventoryUpload
110
124
  end
111
125
  end
112
126
  @stream.simple_field(
113
- 'os_release',
114
- os_release_value(
115
- name: fact_value(host, 'distribution::name'),
116
- version: fact_value(host, 'distribution::version'),
117
- codename: fact_value(host, 'distribution::id')
118
- )
119
- )
127
+ 'os_release', [
128
+ fact_value(host, 'distribution::name'),
129
+ fact_value(host, 'distribution::version'),
130
+ fact_value(host, 'distribution::id'),
131
+ ]
132
+ ) { |v| os_release_value(*v) }
120
133
  @stream.simple_field('os_kernel_version', fact_value(host, 'uname::release'))
121
134
  @stream.simple_field('arch', host.architecture&.name)
122
135
  @stream.simple_field('subscription_status', host.subscription_status_label)
123
136
  @stream.simple_field('katello_agent_running', host.content_facet&.katello_agent_installed?)
124
- @stream.simple_field('satellite_managed', true)
125
137
  @stream.simple_field(
126
138
  'infrastructure_type',
127
139
  ActiveModel::Type::Boolean.new.cast(fact_value(host, 'virt::is_guest')) ? 'virtual' : 'physical'
@@ -137,13 +149,16 @@ module ForemanInventoryUpload
137
149
  end.join(', '))
138
150
  end
139
151
  end
140
- @stream.array_field('installed_packages', :last) do
141
- first = true
142
- host.installed_packages.each do |package|
143
- @stream.raw("#{first ? '' : ', '}#{@stream.stringify_value(package.nvra)}")
144
- first = false
152
+ unless Setting[:exclude_installed_packages]
153
+ @stream.array_field('installed_packages') do
154
+ first = true
155
+ host.installed_packages.each do |package|
156
+ @stream.raw("#{first ? '' : ', '}#{@stream.stringify_value(package.nvra)}")
157
+ first = false
158
+ end
145
159
  end
146
160
  end
161
+ @stream.simple_field('satellite_managed', true, :last)
147
162
  end
148
163
 
149
164
  def report_satellite_facts(host)
@@ -154,6 +169,7 @@ module ForemanInventoryUpload
154
169
  end
155
170
  @stream.simple_field('system_purpose_usage', host.subscription_facet.purpose_usage)
156
171
  @stream.simple_field('system_purpose_role', host.subscription_facet.purpose_role)
172
+ @stream.simple_field('system_purpose_sla', host.subscription_facet.service_level)
157
173
  @stream.simple_field('distribution_version', fact_value(host, 'distribution::version'))
158
174
  @stream.simple_field('satellite_instance_id', Foreman.try(:instance_id))
159
175
  @stream.simple_field('is_simple_content_access', golden_ticket?(host.organization))
@@ -161,7 +177,19 @@ module ForemanInventoryUpload
161
177
  @stream.simple_field('organization_id', host.organization_id, :last)
162
178
  end
163
179
 
164
- def os_release_value(name:, version:, codename:)
180
+ def report_ip_addresses(host, host_ips_cache)
181
+ ip_addresses = host.interfaces.map { |nic| host_ips_cache[nic.ip] }.compact
182
+
183
+ @stream.string_array_value('ip_addresses', ip_addresses)
184
+ end
185
+
186
+ def report_mac_addresses(host)
187
+ macs = host.interfaces.map { |nic| nic.mac }.compact
188
+
189
+ @stream.string_array_value('mac_addresses', macs)
190
+ end
191
+
192
+ def os_release_value(name, version, codename)
165
193
  "#{name} #{version} (#{codename})"
166
194
  end
167
195
  end
@@ -1,4 +1,71 @@
1
1
  require 'foreman_rh_cloud/engine.rb'
2
+ require 'cgi'
3
+ require 'uri'
2
4
 
3
5
  module ForemanRhCloud
6
+ def self.base_url
7
+ # for testing set ENV to 'https://ci.cloud.redhat.com'
8
+ @base_url ||= ENV['SATELLITE_RH_CLOUD_URL'] || 'https://cloud.redhat.com'
9
+ end
10
+
11
+ def self.authentication_url
12
+ # https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
13
+ @authentication_url ||= ENV['SATELLITE_RH_CLOUD_SSO_URL'] || 'https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token'
14
+ end
15
+
16
+ def self.verify_ssl_method
17
+ @verify_ssl_method ||= ENV['SATELLITE_RH_CLOUD_URL'] ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
18
+ end
19
+
20
+ def self.http_proxy_string(logger: Foreman::Logging.logger('background'))
21
+ ForemanRhCloud.proxy_setting(logger: logger)
22
+ end
23
+
24
+ def self.transformed_http_proxy_string(logger: Foreman::Logging.logger('background'))
25
+ ForemanRhCloud.transform_scheme(ForemanRhCloud.proxy_setting(logger: logger))
26
+ end
27
+
28
+ def self.proxy_setting(logger: Foreman::Logging.logger('background'))
29
+ ForemanRhCloud.cdn_proxy(logger: logger) ||
30
+ ForemanRhCloud.global_foreman_proxy ||
31
+ ''
32
+ end
33
+
34
+ def self.cdn_proxy(logger: Foreman::Logging.logger('app'))
35
+ proxy_config = SETTINGS[:katello][:cdn_proxy]
36
+ return nil unless proxy_config
37
+
38
+ uri = URI('')
39
+ uri.host = proxy_config[:host]
40
+ uri.port = proxy_config[:port]
41
+ uri.scheme = proxy_config[:scheme] || 'http'
42
+
43
+ if proxy_config[:user]
44
+ uri.user = CGI.escape(proxy_config[:user])
45
+ uri.password = CGI.escape(proxy_config[:password])
46
+ end
47
+ uri.to_s
48
+ rescue URI::Error => e
49
+ logger.warn("cdn_proxy parsing failed: #{e}")
50
+ nil
51
+ end
52
+
53
+ def self.global_foreman_proxy
54
+ Setting[:http_proxy]
55
+ end
56
+
57
+ # This method assumes uri_string contains uri-encoded username and p@$$word:
58
+ # http://user:p%40%24%24word@localhost:8888
59
+ def self.transform_scheme(uri_string)
60
+ transformed_uri = URI.parse(uri_string)
61
+
62
+ case transformed_uri.scheme
63
+ when "http"
64
+ transformed_uri.scheme = 'proxy'
65
+ when "https"
66
+ transformed_uri.scheme = 'proxys'
67
+ end
68
+
69
+ transformed_uri.to_s
70
+ end
4
71
  end
@@ -13,6 +13,7 @@ module ForemanRhCloud
13
13
  config.autoload_paths += Dir["#{config.root}/app/helpers/concerns"]
14
14
  config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
15
15
  config.autoload_paths += Dir["#{config.root}/app/overrides"]
16
+ config.autoload_paths += Dir["#{config.root}/app/services"]
16
17
  config.autoload_paths += Dir["#{config.root}/lib"]
17
18
 
18
19
  config.eager_load_paths += Dir["#{config.root}/lib"]
@@ -54,20 +55,36 @@ module ForemanRhCloud
54
55
 
55
56
  # Adding a sub menu after hosts menu
56
57
  divider :top_menu, caption: N_('RH Cloud'), parent: :configure_menu
57
- menu :top_menu, :inventory_upload, :caption => N_('Inventory Upload'), :url_hash => { controller: :'foreman_rh_cloud/react', :action => :inventory_upload}, parent: :configure_menu
58
- menu :top_menu, :insights_hits_import, :caption => N_('Insights'), :url_hash => { controller: :'foreman_rh_cloud/react', :action => :insights_cloud }, parent: :configure_menu
58
+ menu :top_menu, :inventory_upload, caption: N_('Inventory Upload'), url_hash: { controller: :'foreman_rh_cloud/react', action: :inventory_upload }, parent: :configure_menu
59
+ menu :top_menu, :insights_hits_import, caption: N_('Insights'), url_hash: { controller: :'foreman_rh_cloud/react', action: :insights_cloud }, parent: :configure_menu
60
+
61
+ register_facet InsightsFacet, :insights do
62
+ set_dependent_action :destroy
63
+ end
59
64
 
60
- register_facet InsightsFacet, :insights
61
65
  register_global_js_file 'subscriptions_extension'
66
+
67
+ register_custom_status(InventorySync::InventoryStatus)
68
+
69
+ extend_page 'hosts/show' do |context|
70
+ context.add_pagelet :main_tabs,
71
+ partial: 'hosts/insights_tab',
72
+ name: _('Insights'),
73
+ onlyif: proc { |host| host.insights }
74
+ end
62
75
  end
63
76
 
64
77
  ::Katello::UINotifications::Subscriptions::ManifestImportSuccess.include ForemanInventoryUpload::Notifications::ManifestImportSuccessNotificationOverride if defined?(Katello)
78
+
79
+ ::Host::Managed.include RhCloudHost
80
+ ::Host::Base.include RhCloudHost
65
81
  end
66
82
 
67
83
  initializer "foreman_rh_cloud.set_dynflow.config.on_init", :before => :finisher_hook do |_app|
68
84
  unless Rails.env.test?
69
85
  ForemanTasks.dynflow.config.on_init do |world|
70
86
  ForemanInventoryUpload::Async::GenerateAllReportsJob.spawn_if_missing(world)
87
+ InsightsCloud::Async::InsightsScheduledSync.spawn_if_missing(world)
71
88
  end
72
89
  end
73
90
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '0.9.8'.freeze
2
+ VERSION = '0.9.13'.freeze
3
3
  end
@@ -1,15 +1,15 @@
1
1
  module InsightsCloud
2
- def self.base_url
3
- # for testing set ENV to 'https://ci.cloud.redhat.com'
4
- @base_url ||= ENV['SATELLITE_INSIGHTS_CLOUD_URL'] || 'https://cloud.redhat.com'
5
- end
2
+ module WebUi
3
+ ADVISOR = 'advisor'
4
+ VULNERABILITY = 'vulnerability'
5
+ PATCH = 'patch'
6
6
 
7
- def self.authentication_url
8
- # https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
9
- @authentication_url ||= ENV['SATELLITE_INSIGHTS_CLOUD_SSO_URL'] || 'https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token'
7
+ def self.system_url(subsystem, host_uuid)
8
+ ForemanRhCloud.base_url + "/insights/#{subsystem}/systems/#{host_uuid}"
9
+ end
10
10
  end
11
11
 
12
12
  def self.hits_export_url
13
- base_url + '/api/insights/v1/export/hits/'
13
+ ForemanRhCloud.base_url + '/api/insights/v1/export/hits/'
14
14
  end
15
15
  end
@@ -3,13 +3,13 @@ require 'rest-client'
3
3
  module InsightsCloud
4
4
  module Async
5
5
  class InsightsFullSync < ::ApplicationJob
6
- def perform(organization)
7
- @organization = organization
6
+ include ::ForemanRhCloud::CloudAuth
8
7
 
8
+ def perform
9
9
  hits = query_insights_hits
10
10
 
11
- host_names = hits.map { |hit| hit['hostname'] }.uniq
12
- setup_host_names(host_names)
11
+ @hits_host_names = Hash[hits.map { |hit| [hit['hostname'], hit['uuid']] }]
12
+ setup_host_names(@hits_host_names.keys)
13
13
 
14
14
  replace_hits_data(hits)
15
15
  end
@@ -18,17 +18,14 @@ module InsightsCloud
18
18
  Foreman::Logging.logger('background')
19
19
  end
20
20
 
21
- def rh_credentials
22
- @rh_credentials ||= query_refresh_token
23
- end
24
-
25
21
  private
26
22
 
27
23
  def query_insights_hits
28
24
  hits_response = RestClient::Request.execute(
29
25
  method: :get,
30
26
  url: InsightsCloud.hits_export_url,
31
- verify_ssl: ENV['SATELLITE_INSIGHTS_CLOUD_URL'] ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER,
27
+ verify_ssl: ForemanRhCloud.verify_ssl_method,
28
+ proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
32
29
  headers: {
33
30
  Authorization: "Bearer #{rh_credentials}",
34
31
  }
@@ -37,27 +34,9 @@ module InsightsCloud
37
34
  JSON.parse(hits_response)
38
35
  end
39
36
 
40
- def query_refresh_token
41
- token_response = RestClient::Request.execute(
42
- method: :post,
43
- url: InsightsCloud.authentication_url,
44
- verify_ssl: ENV['SATELLITE_INSIGHTS_CLOUD_URL'] ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER,
45
- payload: {
46
- grant_type: 'refresh_token',
47
- client_id: 'rhsm-api',
48
- refresh_token: Setting[:rh_cloud_token],
49
- }
50
- )
51
-
52
- JSON.parse(token_response)['access_token']
53
- rescue RestClient::ExceptionWithResponse => e
54
- Foreman::Logging.exception('Unable to authenticate using rh_cloud_token setting', e)
55
- raise ::Foreman::WrappedException.new(e, N_('Unable to authenticate using rh_cloud_token setting'))
56
- end
57
-
58
37
  def setup_host_names(host_names)
59
38
  @host_ids = Hash[
60
- Host.where(name: host_names).pluck(:name, :id)
39
+ Host.unscoped.where(name: host_names).pluck(:name, :id)
61
40
  ]
62
41
  end
63
42
 
@@ -67,17 +46,30 @@ module InsightsCloud
67
46
 
68
47
  def replace_hits_data(hits)
69
48
  InsightsHit.transaction do
70
- InsightsHit.delete_all
71
- InsightsHit.create(hits.map { |hits_hash| to_model_hash(hits_hash) })
72
49
  # create new facets for hosts that are missing one
73
50
  hosts_with_existing_facets = InsightsFacet.where(host_id: @host_ids.values).pluck(:host_id)
74
- InsightsFacet.create((@host_ids.values - hosts_with_existing_facets).map { |id| {host_id: id} })
51
+ InsightsFacet.create(
52
+ @host_ids.map do |host_name, host_id|
53
+ unless hosts_with_existing_facets.include?(host_id)
54
+ {
55
+ host_id: host_id,
56
+ uuid: @hits_host_names[host_name],
57
+ }
58
+ end
59
+ end.compact
60
+ )
61
+ InsightsHit.delete_all
62
+ InsightsHit.create(hits.map { |hits_hash| to_model_hash(hits_hash) }.compact)
75
63
  end
76
64
  end
77
65
 
78
66
  def to_model_hash(hit_hash)
67
+ hit_host_id = host_id(hit_hash['hostname'])
68
+
69
+ return unless hit_host_id
70
+
79
71
  {
80
- host_id: host_id(hit_hash['hostname']),
72
+ host_id: hit_host_id,
81
73
  last_seen: Time.parse(hit_hash['last_seen']),
82
74
  publish_date: Time.parse(hit_hash['publish_date']),
83
75
  title: hit_hash['title'],