foreman_rh_cloud 12.2.0 → 12.2.2

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/rh_cloud/advisor_engine_config_controller.rb +1 -1
  3. data/app/controllers/api/v2/rh_cloud/cloud_request_controller.rb +3 -0
  4. data/app/controllers/api/v2/rh_cloud/inventory_controller.rb +3 -0
  5. data/app/controllers/concerns/foreman_rh_cloud/iop_smart_proxy_access.rb +28 -0
  6. data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +1 -1
  7. data/app/controllers/foreman_inventory_upload/uploads_controller.rb +3 -0
  8. data/app/controllers/foreman_rh_cloud/foreman_rh_cloud_controller.rb +22 -0
  9. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +19 -5
  10. data/app/controllers/insights_cloud/ui_requests_controller.rb +11 -0
  11. data/app/services/foreman_rh_cloud/cert_auth.rb +1 -1
  12. data/app/services/foreman_rh_cloud/cloud_request.rb +1 -1
  13. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +1 -1
  14. data/app/services/foreman_rh_cloud/hit_remediations_retriever.rb +27 -10
  15. data/app/services/foreman_rh_cloud/url_remediations_retriever.rb +1 -1
  16. data/app/views/api/v2/hosts/insights/base.rabl +2 -2
  17. data/app/views/api/v2/hosts/insights/single.rabl +1 -1
  18. data/config/routes.rb +8 -14
  19. data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +2 -2
  20. data/lib/foreman_inventory_upload/async/upload_report_job.rb +1 -1
  21. data/lib/foreman_inventory_upload/generators/slice.rb +24 -0
  22. data/lib/foreman_rh_cloud/engine.rb +8 -131
  23. data/lib/foreman_rh_cloud/plugin.rb +150 -0
  24. data/lib/foreman_rh_cloud/version.rb +1 -1
  25. data/lib/foreman_rh_cloud.rb +5 -6
  26. data/lib/insights_cloud/async/insights_scheduled_sync.rb +2 -2
  27. data/lib/inventory_sync/async/inventory_hosts_sync.rb +1 -1
  28. data/lib/inventory_sync/async/inventory_scheduled_sync.rb +2 -2
  29. data/lib/tasks/insights.rake +1 -1
  30. data/lib/tasks/rh_cloud_inventory.rake +20 -2
  31. data/package.json +1 -1
  32. data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +20 -3
  33. data/test/controllers/insights_cloud/ui_requests_controller_test.rb +23 -0
  34. data/test/controllers/insights_sync/settings_controller_test.rb +1 -1
  35. data/test/factories/inventory_upload_factories.rb +4 -112
  36. data/test/jobs/inventory_scheduled_sync_test.rb +3 -3
  37. data/test/test_plugin_helper.rb +8 -2
  38. data/test/unit/rh_cloud_http_proxy_test.rb +3 -3
  39. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +4 -1
  40. data/test/unit/slice_generator_test.rb +33 -0
  41. data/test/unit/tags_generator_test.rb +4 -1
  42. data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +2 -1
  43. data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.scss +3 -0
  44. data/webpack/CveDetailsPage/CveDetailsPage.js +1 -1
  45. data/webpack/CveDetailsPage/CveDetailsPage.test.js +1 -3
  46. data/webpack/ForemanColumnExtensions/index.js +20 -15
  47. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +23 -0
  48. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/PageDescription.test.js +2 -0
  49. data/webpack/ForemanRhCloudPages.js +1 -0
  50. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationHelpers.js +26 -4
  51. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +85 -11
  52. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +39 -5
  53. data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +13 -0
  54. data/webpack/InsightsCloudSync/InsightsCloudSync.js +9 -7
  55. data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +16 -15
  56. data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js +1 -1
  57. data/webpack/IopRecommendationDetails/IopRecommendationDetails.js +1 -11
  58. data/webpack/common/Hooks/ConfigHooks.js +1 -2
  59. data/webpack/common/styles.scss +7 -0
  60. metadata +6 -1
@@ -0,0 +1,150 @@
1
+ module ForemanRhCloud
2
+ module Plugin
3
+ def self.register
4
+ # This module is auto-loaded, but plugin settings cannot be redefined
5
+ # Ensure that we don't try to re-register the plugin on code reload
6
+ return if Foreman::Plugin.find(:foreman_rh_cloud)
7
+
8
+ Foreman::Plugin.register :foreman_rh_cloud do
9
+ requires_foreman '>= 3.13'
10
+ register_gettext
11
+
12
+ apipie_documented_controllers ["#{ForemanRhCloud::Engine.root}/app/controllers/api/v2/**/*.rb"]
13
+
14
+ settings do
15
+ category(:rh_cloud, N_('Insights')) do
16
+ setting('allow_auto_inventory_upload', type: :boolean, description: N_('Enable automatic upload of your host inventory to the Red Hat cloud'), default: true, full_name: N_('Automatic inventory upload'))
17
+ setting('allow_auto_insights_sync', type: :boolean, description: N_('Enable automatic synchronization of Insights recommendations from the Red Hat cloud'), default: true, full_name: N_('Synchronize recommendations Automatically'))
18
+ setting('allow_auto_insights_mismatch_delete', type: :boolean, description: N_('Enable automatic deletion of mismatched host records from the Red Hat cloud'), default: false, full_name: N_('Automatic mismatch deletion'))
19
+ setting('obfuscate_inventory_hostnames', type: :boolean, description: N_('Obfuscate host names sent to the Red Hat cloud. (If insights_minimal_data_collection is set to true, this setting is ignored because host names are not included in the report.)'), default: false, full_name: N_('Obfuscate host names'))
20
+ setting('obfuscate_inventory_ips', type: :boolean, description: N_('Obfuscate ipv4 addresses sent to the Red Hat cloud. (If insights_minimal_data_collection is set to true, this setting is ignored because host IPv4 addresses are not included in the report.)'), default: false, full_name: N_('Obfuscate host ipv4 addresses.'))
21
+ setting('exclude_installed_packages', type: :boolean, description: N_('Exclude installed packages from being uploaded to the Red Hat cloud. (If insights_minimal_data_collection is set to true, this setting is ignored and installed packages are always excluded.)'), default: false, full_name: N_("Exclude installed packages"))
22
+ setting('include_parameter_tags', type: :boolean, description: N_('Should import include parameter tags from Foreman?'), default: false, full_name: N_('Include parameters in insights-client reports'))
23
+ setting('rhc_instance_id', type: :string, description: N_('RHC daemon id'), default: nil, full_name: N_('ID of the RHC(Yggdrasil) daemon'))
24
+ setting('insights_minimal_data_collection', type: :boolean, default: false, full_name: N_('Minimal data collection'), description: N_('Only include the minimum required data in inventory reports for uploading to Red Hat cloud. When this is true, installed packages are excluded from the report regardless of the exclude_installed_packages setting, and host names and IPv4 addresses are excluded from the report regardless of obfuscation settings.'))
25
+ end
26
+ end
27
+
28
+ # Add permissions
29
+ security_block :foreman_rh_cloud do
30
+ permission(
31
+ :generate_foreman_rh_cloud,
32
+ 'foreman_inventory_upload/reports': [:generate],
33
+ 'foreman_inventory_upload/tasks': [:create],
34
+ 'api/v2/rh_cloud/inventory': [:get_hosts, :remove_hosts, :sync_inventory_status, :download_file, :generate_report, :enable_cloud_connector],
35
+ 'foreman_inventory_upload/uploads': [:enable_cloud_connector],
36
+ 'foreman_inventory_upload/uploads_settings': [:set_advanced_setting],
37
+ 'foreman_inventory_upload/missing_hosts': [:remove_hosts],
38
+ 'insights_cloud/settings': [:update],
39
+ 'insights_cloud/tasks': [:create]
40
+ )
41
+ permission(
42
+ :view_foreman_rh_cloud,
43
+ 'foreman_inventory_upload/accounts': [:index],
44
+ 'foreman_inventory_upload/reports': [:last],
45
+ 'foreman_inventory_upload/uploads': [:auto_upload, :show_auto_upload, :download_file, :last],
46
+ 'foreman_inventory_upload/tasks': [:show],
47
+ 'foreman_inventory_upload/cloud_status': [:index],
48
+ 'foreman_inventory_upload/uploads_settings': [:index],
49
+ 'foreman_inventory_upload/missing_hosts': [:index],
50
+ 'api/v2/rh_cloud/advisor_engine_config': [:show],
51
+ 'foreman_rh_cloud/foreman_rh_cloud': [:inventory_upload, :recommendations],
52
+ 'react': [:index]
53
+ )
54
+ permission(
55
+ :view_insights_hits,
56
+ {
57
+ '/foreman_rh_cloud/insights_cloud': [:index], # for bookmarks and later for showing the page
58
+ 'insights_cloud/hits': [:index, :show, :auto_complete_search, :resolutions],
59
+ 'insights_cloud/settings': [:index, :show],
60
+ 'insights_cloud/ui_requests': [:forward_request, :translate_insights_host],
61
+ 'react': [:index],
62
+ },
63
+ :resource_type => ::InsightsHit.name
64
+ )
65
+ permission(
66
+ :dispatch_cloud_requests,
67
+ 'api/v2/rh_cloud/cloud_request': [:update]
68
+ )
69
+ permission(
70
+ :control_organization_insights,
71
+ 'insights_cloud/settings': [:set_org_parameter]
72
+ )
73
+ end
74
+
75
+ plugin_permissions = [:view_foreman_rh_cloud, :generate_foreman_rh_cloud, :view_insights_hits, :dispatch_cloud_requests, :control_organization_insights]
76
+
77
+ role 'ForemanRhCloud', plugin_permissions, 'Role granting permissions to view the hosts inventory,
78
+ generate a report, upload it to the cloud and download it locally'
79
+
80
+ add_permissions_to_default_roles Role::ORG_ADMIN => plugin_permissions,
81
+ Role::MANAGER => plugin_permissions,
82
+ Role::SYSTEM_ADMIN => plugin_permissions
83
+
84
+ # Adding a top-level menu item
85
+ sub_menu :top_menu, :insights_menu, caption: N_('Insights'), icon: 'fa fa-cloud', after: :hosts_menu do
86
+ menu :top_menu,
87
+ :inventory_upload,
88
+ caption: N_('Inventory Upload'),
89
+ url: '/foreman_rh_cloud/inventory_upload',
90
+ url_hash: { controller: :react, action: :index },
91
+ parent: :insights_menu,
92
+ if: -> { !ForemanRhCloud.with_iop_smart_proxy? }
93
+ menu :top_menu, :insights_hits, caption: N_('Recommendations'), url: '/foreman_rh_cloud/insights_cloud', url_hash: { controller: :react, action: :index }, parent: :insights_menu
94
+ menu :top_menu,
95
+ :insights_vulnerability,
96
+ caption: N_('Vulnerability'),
97
+ url: '/foreman_rh_cloud/insights_vulnerability',
98
+ url_hash: { controller: :react, action: :index },
99
+ parent: :insights_menu,
100
+ if: -> { ForemanRhCloud.with_iop_smart_proxy? }
101
+ end
102
+
103
+ # In IoP case we want the page to be in the admin menu
104
+ menu :admin_menu,
105
+ :inventory_upload,
106
+ caption: N_('Inventory Upload'),
107
+ url: '/foreman_rh_cloud/inventory_upload',
108
+ url_hash: { controller: :react, action: :index },
109
+ parent: :administer_menu,
110
+ before: :upgrade,
111
+ if: -> { ForemanRhCloud.with_iop_smart_proxy? }
112
+
113
+ register_facet InsightsFacet, :insights do
114
+ configure_host do
115
+ api_view :list => 'api/v2/hosts/insights/insights', :single => 'api/v2/hosts/insights/single'
116
+ set_dependent_action :destroy
117
+ end
118
+ end
119
+
120
+ register_global_js_file 'global'
121
+
122
+ register_custom_status InventorySync::InventoryStatus
123
+ register_custom_status InsightsClientReportStatus
124
+
125
+ describe_host do
126
+ overview_buttons_provider :insights_host_overview_buttons
127
+ end
128
+
129
+ extend_page 'hosts/show' do |context|
130
+ context.add_pagelet :main_tabs,
131
+ partial: 'hosts/insights_tab',
132
+ name: _('Insights'),
133
+ id: 'insights',
134
+ onlyif: proc { |host| host.insights }
135
+ end
136
+
137
+ extend_page 'hosts/_list' do |context|
138
+ context.with_profile :cloud, _('RH Cloud'), default: true do
139
+ add_pagelet :hosts_table_column_header, key: :insights_recommendations_count, label: _('Recommendations'), sortable: true, width: '12%', class: 'hidden-xs ellipsis', priority: 100,
140
+ export_data: CsvExporter::ExportDefinition.new(:insights_recommendations_count, callback: ->(host) { host&.insights_hits&.count })
141
+ add_pagelet :hosts_table_column_content, key: :insights_recommendations_count, callback: ->(host) { hits_counts_cell(host) }, class: 'hidden-xs ellipsis text-center', priority: 100
142
+ end
143
+ end
144
+
145
+ extend_template_helpers ForemanRhCloud::TemplateRendererHelper
146
+ allowed_template_helpers :remediations_playbook, :download_rh_playbook
147
+ end
148
+ end
149
+ end
150
+ end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '12.2.0'.freeze
2
+ VERSION = '12.2.2'.freeze
3
3
  end
@@ -4,13 +4,12 @@ require 'uri'
4
4
 
5
5
  module ForemanRhCloud
6
6
  def self.on_premise_url
7
- return unless ForemanRhCloud.with_local_advisor_engine?
8
- port = ENV['ADVISOR_ENGINE_PORT'] || "24443"
9
- ENV['ADVISOR_ENGINE_URL'] || "https://localhost:#{port}"
7
+ return unless ForemanRhCloud.with_iop_smart_proxy?
8
+ ForemanRhCloud.iop_smart_proxy&.url
10
9
  end
11
10
 
12
11
  def self.env_or_on_premise_url(env_var_name)
13
- ENV[env_var_name] || on_premise_url
12
+ on_premise_url || ENV[env_var_name]
14
13
  end
15
14
 
16
15
  def self.base_url
@@ -47,7 +46,7 @@ module ForemanRhCloud
47
46
  end
48
47
 
49
48
  def self.proxy_string
50
- return '' if ForemanRhCloud.with_local_advisor_engine?
49
+ return '' if ForemanRhCloud.with_iop_smart_proxy?
51
50
 
52
51
  HttpProxy.default_global_content_proxy&.full_url ||
53
52
  ForemanRhCloud.global_foreman_proxy ||
@@ -106,7 +105,7 @@ module ForemanRhCloud
106
105
  end
107
106
 
108
107
  def self.legacy_insights_ca
109
- "#{ForemanRhCloud::Engine.root}/config/rh_cert-api_chain.pem" unless ForemanRhCloud.with_local_advisor_engine?
108
+ "#{ForemanRhCloud::Engine.root}/config/rh_cert-api_chain.pem" unless ForemanRhCloud.with_iop_smart_proxy?
110
109
  end
111
110
 
112
111
  def self.cloud_url_validator
@@ -13,7 +13,7 @@ module InsightsCloud
13
13
  return
14
14
  end
15
15
 
16
- if ForemanRhCloud.with_local_advisor_engine?
16
+ if ForemanRhCloud.with_iop_smart_proxy?
17
17
  plan_self
18
18
  else
19
19
  after_delay do
@@ -23,7 +23,7 @@ module InsightsCloud
23
23
  end
24
24
 
25
25
  def run
26
- output[:status] = _('The scheduled process is disabled because this Foreman is configured with the use_local_advisor_engine option.') if ForemanRhCloud.with_local_advisor_engine?
26
+ output[:status] = _('The scheduled process is disabled because this Foreman is configured with a local IoP Smart Proxy.') if ForemanRhCloud.with_iop_smart_proxy?
27
27
  end
28
28
 
29
29
  def plan_full_sync
@@ -9,7 +9,7 @@ module InventorySync
9
9
 
10
10
  def plan(organizations)
11
11
  # Do not run for local advisor, since we use sub-man id to identify hosts.
12
- return if ForemanRhCloud.with_local_advisor_engine?
12
+ return if ForemanRhCloud.with_iop_smart_proxy?
13
13
  # by default the tasks will be executed concurrently
14
14
  super(organizations)
15
15
  plan_self_host_sync
@@ -13,7 +13,7 @@ module InventorySync
13
13
  return
14
14
  end
15
15
 
16
- if ForemanRhCloud.with_local_advisor_engine?
16
+ if ForemanRhCloud.with_iop_smart_proxy?
17
17
  plan_self # so that 'run' runs
18
18
  else
19
19
  after_delay do
@@ -35,7 +35,7 @@ module InventorySync
35
35
  end
36
36
 
37
37
  def run
38
- output[:status] = _('The scheduled process is disabled because this Foreman is configured with the use_local_advisor_engine option.') if ForemanRhCloud.with_local_advisor_engine?
38
+ output[:status] = _('The scheduled process is disabled because this Foreman is configured with a local IoP Smart Proxy.') if ForemanRhCloud.with_iop_smart_proxy?
39
39
  end
40
40
 
41
41
  def plan_remove_insights_hosts(org_id)
@@ -24,7 +24,7 @@ namespace :rh_cloud_insights do
24
24
  desc "Re-announce all organizations into Sources on RH cloud."
25
25
  task announce_to_sources: [:environment] do
26
26
  logger = Logging::Logger.new(STDOUT)
27
- if ForemanRhCloud.with_local_advisor_engine?
27
+ if ForemanRhCloud.with_iop_smart_proxy?
28
28
  logger.warn('Task announce_to_sources is not available when using local advisor engine')
29
29
  else
30
30
  Organization.unscoped.each do |org|
@@ -9,7 +9,7 @@ namespace :rh_cloud_inventory do
9
9
  else
10
10
  organizations = [Organization.where(:id => ENV['organization_id']).first]
11
11
  end
12
- disconnected = ForemanRhCloud.with_local_advisor_engine?
12
+ disconnected = ForemanRhCloud.with_iop_smart_proxy?
13
13
  User.as_anonymous_admin do
14
14
  organizations.each do |organization|
15
15
  ForemanTasks.async_task(
@@ -45,6 +45,24 @@ namespace :rh_cloud_inventory do
45
45
  archived_report_generator = ForemanInventoryUpload::Generators::ArchivedReport.new(target, Logger.new(STDOUT))
46
46
  archived_report_generator.render(organization: organization, filter: filter)
47
47
  puts "Successfully generated #{target} for organization id #{organization}"
48
+
49
+ next unless ForemanRhCloud.with_iop_smart_proxy?
50
+
51
+ puts 'Creating missing insights facets'
52
+ hosts_without_facets = ForemanInventoryUpload::Generators::Queries.for_org(organization, hosts_query: 'null? insights_uuid')
53
+ hosts_without_facets.each do |batch|
54
+ facets = batch.pluck(:id, 'katello_subscription_facets.uuid').map do |host_id, uuid|
55
+ {
56
+ host_id: host_id,
57
+ uuid: uuid,
58
+ }
59
+ end
60
+ # We don't need to validate the facets here as we create the necessary fields.
61
+ # rubocop:disable Rails/SkipsModelValidations
62
+ InsightsFacet.upsert_all(facets, unique_by: :host_id) unless facets.empty?
63
+ # rubocop:enable Rails/SkipsModelValidations
64
+ end
65
+ puts 'Missing Insights facets created'
48
66
  end
49
67
  end
50
68
  end
@@ -53,7 +71,7 @@ namespace :rh_cloud_inventory do
53
71
  base_folder = ENV['target'] || ForemanInventoryUpload.generated_reports_folder
54
72
  organization_id = ENV['organization_id']
55
73
  report_file = ForemanInventoryUpload.facts_archive_name(organization_id)
56
- disconnected = ForemanRhCloud.with_local_advisor_engine?
74
+ disconnected = ForemanRhCloud.with_iop_smart_proxy?
57
75
  ForemanTasks.sync_task(ForemanInventoryUpload::Async::QueueForUploadJob, base_folder, report_file, organization_id, disconnected)
58
76
  puts "Uploaded #{report_file}"
59
77
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "12.2.0",
3
+ "version": "12.2.2",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -17,8 +17,8 @@ module InsightsCloud::Api
17
17
  @http_req = RestClient::Request.new(:method => 'GET', :url => 'http://test.theforeman.org')
18
18
 
19
19
  org = FactoryBot.create(:organization)
20
- host = FactoryBot.create(:host, :with_subscription, :organization => org)
21
- User.current = ::Katello::CpConsumerUser.new(:uuid => host.subscription_facet.uuid, :login => host.subscription_facet.uuid)
20
+ @host = FactoryBot.create(:host, :with_subscription, :organization => org)
21
+ User.current = ::Katello::CpConsumerUser.new(:uuid => @host.subscription_facet.uuid, :login => @host.subscription_facet.uuid)
22
22
  InsightsCloud::Api::MachineTelemetriesController.any_instance.stubs(:upstream_owner).returns({ 'uuid' => 'abcdefg' })
23
23
 
24
24
  setup_certs_expectation do
@@ -151,6 +151,20 @@ module InsightsCloud::Api
151
151
  assert_equal 'Cloud request failed', JSON.parse(@response.body)['message']
152
152
  assert_match /#{@body}/, JSON.parse(@response.body)['response']
153
153
  end
154
+
155
+ test "should create insights facet" do
156
+ assert_nil InsightsFacet.find_by(host_id: @host.id)
157
+ ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
158
+ req = RestClient::Request.new(:method => 'GET', :url => 'http://test.theforeman.org/')
159
+ net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
160
+ net_http_resp[:content_type] = 'application/zip'
161
+ res = RestClient::Response.create(@body, net_http_resp, req)
162
+ ::ForemanRhCloud::CloudRequestForwarder.any_instance.stubs(:forward_request).returns(res)
163
+
164
+ get :forward_request, params: { "path" => "/redhat_access/r/insights/uploads/" }
165
+
166
+ assert_not_nil InsightsFacet.find_by(host_id: @host.id)
167
+ end
154
168
  end
155
169
 
156
170
  context '#branch_info' do
@@ -166,7 +180,10 @@ module InsightsCloud::Api
166
180
  :with_content,
167
181
  :with_hostgroup,
168
182
  :with_parameter,
169
- content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)],
183
+ content_facet: FactoryBot.build(
184
+ :content_facet,
185
+ content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)]
186
+ ),
170
187
  organization: env.organization
171
188
  )
172
189
 
@@ -9,6 +9,29 @@ module InsightsCloud
9
9
  FactoryBot.create(:common_parameter, name: InsightsCloud.enable_client_param, key_type: 'boolean', value: true)
10
10
  end
11
11
 
12
+ context '#translate_insights_host' do
13
+ setup do
14
+ @org = FactoryBot.create(:organization)
15
+ @loc = FactoryBot.create(:location)
16
+ @host = FactoryBot.create(:host, :with_subscription, :organization => @org)
17
+ @facet = InsightsFacet.create(host: @host, uuid: @host.subscription_facet.uuid)
18
+ end
19
+
20
+ test "should redirect to host details page by id" do
21
+ get :translate_insights_host, params: { "uuid" => @host.subscription_facet.uuid }, session: set_session
22
+ assert_equal 302, @response.status
23
+ assert @response.redirect?
24
+ assert_equal "http://test.host/new/hosts/#{@host.id}", @response.redirect_url
25
+ end
26
+
27
+ test "should redirect to not-found page" do
28
+ get :translate_insights_host, params: { "uuid" => "foo" }, session: set_session
29
+ assert_equal 302, @response.status
30
+ assert @response.redirect?
31
+ assert_equal "http://test.host/page-not-found", @response.redirect_url
32
+ end
33
+ end
34
+
12
35
  context '#forward_request' do
13
36
  include MockCerts
14
37
 
@@ -3,7 +3,7 @@ require 'test_plugin_helper'
3
3
  class SettingsControllerTest < ActionController::TestCase
4
4
  tests InsightsCloud::SettingsController
5
5
  def setup
6
- ForemanRhCloud.stubs(:with_local_advisor_engine?).returns(false)
6
+ ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
7
7
  end
8
8
 
9
9
  test 'should return allow_auto_insights_sync setting' do
@@ -1,87 +1,3 @@
1
- # redefine katello factories, as long as katello is not compatible with dynamic properties
2
- FactoryBot.define do
3
- factory :katello_organization, :class => "Organization" do
4
- type { "Organization" }
5
- sequence(:name) { |n| "Organization#{n}" }
6
- sequence(:label) { |n| "org#{n}" }
7
- sequence(:id) { |n| n }
8
-
9
- trait :acme_corporation do
10
- name { "ACME_Corporation" }
11
- type { "Organization" }
12
- description { "This is the first Organization." }
13
- label { "acme_corporation_label" }
14
- end
15
-
16
- trait :with_library do
17
- association :library, :factory => :katello_library
18
- end
19
-
20
- factory :acme_corporation, :traits => [:acme_corporation]
21
- end
22
- end
23
-
24
- FactoryBot.define do
25
- factory :katello_content_view, :class => Katello::ContentView do
26
- sequence(:name) { |n| "Database#{n}" }
27
- description { "This content view is for database content" }
28
- association :organization, :factory => :katello_organization
29
-
30
- trait :composite do
31
- composite { true }
32
- end
33
- end
34
- end
35
-
36
- FactoryBot.define do
37
- factory :katello_content_view_environment, :class => Katello::ContentViewEnvironment do
38
- sequence(:name) { |n| "name#{n}" }
39
- sequence(:label) { |n| "label#{n}" }
40
- end
41
- end
42
-
43
- FactoryBot.define do
44
- factory :katello_k_t_environment, :aliases => [:katello_environment], :class => Katello::KTEnvironment do
45
- sequence(:name) { |n| "Environment#{n}" }
46
- sequence(:label) { |n| "environment#{n}" }
47
- association :organization, :factory => :katello_organization
48
- end
49
- end
50
-
51
- FactoryBot.define do
52
- factory :katello_content_facets, :aliases => [:content_facet], :class => ::Katello::Host::ContentFacet do
53
- sequence(:uuid) { |n| "uuid-#{n}" }
54
- end
55
- end
56
-
57
- FactoryBot.define do
58
- factory :katello_subscription_facets, :aliases => [:subscription_facet], :class => ::Katello::Host::SubscriptionFacet do
59
- sequence(:uuid) { |n| "00000000-%<n>04d-%<r>04d-0000-000000000000" % { n: n, r: rand(500) } }
60
- facts { { 'memory.memtotal' => "12 GB" } }
61
- end
62
- end
63
-
64
- FactoryBot.define do
65
- factory :katello_subscription, :class => Katello::Subscription do
66
- end
67
- end
68
-
69
- FactoryBot.define do
70
- factory :katello_pool, :class => Katello::Pool do
71
- active { true }
72
- end_date { Date.today + 1.year }
73
- cp_id { 1 }
74
-
75
- association :organization, :factory => :katello_organization
76
-
77
- after(:build) do |pool, _evaluator|
78
- pool.subscription.organization = pool.organization
79
- end
80
-
81
- association :subscription, :factory => :katello_subscription
82
- end
83
- end
84
-
85
1
  FactoryBot.define do
86
2
  factory :katello_host_collection_host, :class => Katello::HostCollectionHosts do
87
3
  host_id { nil }
@@ -94,34 +10,10 @@ FactoryBot.define do
94
10
  end
95
11
  end
96
12
 
13
+ # Fix Katello factories to return a valid UUID
97
14
  FactoryBot.modify do
98
- factory :host do
99
- transient do
100
- content_view { nil }
101
- lifecycle_environment { nil }
102
- content_source { nil }
103
- content_view_environments { [] }
104
- end
105
-
106
- trait :with_content do
107
- association :content_facet, :factory => :content_facet, :strategy => :build
108
-
109
- after(:build) do |host, evaluator|
110
- if host.content_facet
111
- if evaluator.content_view && evaluator.lifecycle_environment
112
- host.content_facet.assign_single_environment(
113
- content_view_id: evaluator.content_view.id,
114
- lifecycle_environment_id: evaluator.lifecycle_environment.id
115
- )
116
- end
117
- host.content_facet.content_source = evaluator.content_source if evaluator.content_source
118
- host.content_facet.content_view_environments = evaluator.content_view_environments unless evaluator.content_view_environments.empty?
119
- end
120
- end
121
- end
122
-
123
- trait :with_subscription do
124
- association :subscription_facet, :factory => :subscription_facet, :strategy => :build
125
- end
15
+ factory :katello_subscription_facets, :aliases => [:subscription_facet], :class => ::Katello::Host::SubscriptionFacet do
16
+ sequence(:uuid) { |n| "00000000-%<n>04d-%<r>04d-0000-000000000000" % { n: n, r: rand(500) } }
17
+ facts { { 'memory.memtotal' => "12 GB" } }
126
18
  end
127
19
  end
@@ -14,14 +14,14 @@ class InventoryScheduledSyncTest < ActiveSupport::TestCase
14
14
  ForemanTasks.sync_task(InventorySync::Async::InventoryScheduledSync)
15
15
  end
16
16
 
17
- test 'Skips execution if with_local_advisor_engine? is true' do
18
- ForemanRhCloud.stubs(:with_local_advisor_engine?).returns(true)
17
+ test 'Skips execution if with_iop_smart_proxy? is true' do
18
+ ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
19
19
 
20
20
  InventorySync::Async::InventoryScheduledSync.any_instance.expects(:plan_org_sync).never
21
21
 
22
22
  task = ForemanTasks.sync_task(InventorySync::Async::InventoryScheduledSync)
23
23
  status = task.output[:status].to_s
24
- assert_match(/Foreman is configured with the use_local_advisor_engine option/, status)
24
+ assert_match(/Foreman is configured with a local IoP Smart Proxy/, status)
25
25
  end
26
26
 
27
27
  test 'Skips execution if auto upload is disabled' do
@@ -2,10 +2,16 @@
2
2
  require 'test_helper'
3
3
 
4
4
  # Add plugin to FactoryBot's paths
5
- FactoryBot.definition_file_paths << "#{ForemanTasks::Engine.root}/test/factories"
5
+ katello_files = Dir.glob("#{Katello::Engine.root}/test/factories/**/*.rb")
6
+ FactoryBot.definition_file_paths +=
7
+ katello_files
8
+ # skip foreman_task factories, since we already have those definitions in ForemanTasks
9
+ .reject { |f| f =~ /foreman_task|recurring_logic/ }
10
+ .map { |f| f.gsub('.rb', '') } # .rb extension is will be appended by factorybot
6
11
  FactoryBot.definition_file_paths << "#{ForemanRemoteExecution::Engine.root}/test/factories"
12
+ FactoryBot.definition_file_paths << "#{ForemanTasks::Engine.root}/test/factories"
13
+
7
14
  FactoryBot.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
8
- # FactoryBot.definition_file_paths << "#{Katello::Engine.root}/test/factories"
9
15
  FactoryBot.reload
10
16
 
11
17
  begin
@@ -4,7 +4,7 @@ class RhCloudHttpProxyTest < ActiveSupport::TestCase
4
4
  setup do
5
5
  @global_content_proxy_mock = 'http://global:content@localhost:80'
6
6
  @global_foreman_proxy_mock = 'http://global:foreman@localhost:80'
7
- ForemanRhCloud.stubs(:with_local_advisor_engine?).returns(false)
7
+ ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
8
8
  end
9
9
 
10
10
  test 'selects global content proxy' do
@@ -20,8 +20,8 @@ class RhCloudHttpProxyTest < ActiveSupport::TestCase
20
20
  end
21
21
 
22
22
  test 'returns empty string in on-prem setup' do
23
- ForemanRhCloud.unstub(:with_local_advisor_engine?)
24
- ForemanRhCloud.stubs(:with_local_advisor_engine?).returns(true)
23
+ ForemanRhCloud.unstub(:with_iop_smart_proxy?)
24
+ ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
25
25
 
26
26
  assert_empty ForemanRhCloud.proxy_setting
27
27
  end
@@ -22,7 +22,10 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
22
22
  :with_content,
23
23
  :with_hostgroup,
24
24
  :with_parameter,
25
- content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)],
25
+ content_facet: FactoryBot.build(
26
+ :content_facet,
27
+ content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)]
28
+ ),
26
29
  organization: env.organization
27
30
  )
28
31
 
@@ -998,6 +998,39 @@ class SliceGeneratorTest < ActiveSupport::TestCase
998
998
  assert_not_nil actual_host['insights_id']
999
999
  end
1000
1000
 
1001
+ test 'reports yum repos' do
1002
+ ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
1003
+ FactoryBot.create(:katello_content, cp_content_id: '1', organization: @host.organization, name: 'Test Content', label: 'test-content')
1004
+ repo = FactoryBot.build(
1005
+ :katello_repository,
1006
+ :fedora_17_x86_64_dev,
1007
+ :with_content_view,
1008
+ product: FactoryBot.create(:katello_product, :redhat, :with_provider, organization: @host.organization)
1009
+ )
1010
+ # force-save the root repo to avoid validation errors
1011
+ repo.root.save(validate: false)
1012
+ repo.save(validate: false)
1013
+ @host.content_facet.bound_repositories << repo
1014
+ @host.content_facet.content_source = FactoryBot.create(:smart_proxy, :with_pulp3)
1015
+ @host.save(validate: false)
1016
+
1017
+ batch = Host.where(id: @host.id).in_batches.first
1018
+ generator = create_generator(batch)
1019
+ json_str = generator.render
1020
+ actual = JSON.parse(json_str.join("\n"))
1021
+
1022
+ assert_not_nil(actual_host = actual['hosts'].first)
1023
+ assert_not_nil(actual_system_profile = actual_host['system_profile'])
1024
+ assert_not_nil(actual_yum_repos = actual_system_profile['yum_repos'])
1025
+ assert_equal 1, actual_yum_repos.count
1026
+ assert_not_nil(actual_yum_repo = actual_yum_repos.first)
1027
+ assert_equal 'Test Content', actual_yum_repo['name']
1028
+ assert_equal 'test-content', actual_yum_repo['id']
1029
+ assert_match(/fedora_17/, actual_yum_repo['base_url'])
1030
+ assert_equal true, actual_yum_repo['enabled']
1031
+ assert_equal true, actual_yum_repo['gpgcheck']
1032
+ end
1033
+
1001
1034
  private
1002
1035
 
1003
1036
  def create_generator(batch, name = '00000000-0000-0000-0000-000000000000')
@@ -26,7 +26,10 @@ class TagsGeneratorTest < ActiveSupport::TestCase
26
26
  organization: env.organization,
27
27
  location: @location2,
28
28
  hostgroup: @hostgroup2,
29
- content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)]
29
+ content_facet: FactoryBot.build(
30
+ :content_facet,
31
+ content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)]
32
+ )
30
33
  )
31
34
 
32
35
  @host.organization.pools << FactoryBot.create(:katello_pool, account_number: '1234', cp_id: 1)
@@ -2,12 +2,13 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
4
4
  import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
5
+ import './CVEsHostDetailsTab.scss';
5
6
 
6
7
  const CVEsHostDetailsTab = ({ systemId }) => {
7
8
  const scope = 'vulnerability';
8
9
  const module = './SystemDetailTable';
9
10
  return (
10
- <div className="rh-cloud-insights-vulnerability-host-details-component">
11
+ <div className="rh-cloud-insights-vulnerability-host-details-component vulnerability">
11
12
  <ScalprumComponent scope={scope} module={module} systemId={systemId} />
12
13
  </div>
13
14
  );