foreman_rh_cloud 3.0.21.1 → 4.0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d87599d8ef67eeeaa3e17e720dc990b58d4085caf7fb6491dab093c54770c8fd
4
- data.tar.gz: 04b52a7412dddf8e6829d61555ec9315c7f3856fde32e976eb8c50638082a3bc
3
+ metadata.gz: 97882071192995f2da93032050b9ecdfa616dba407c8d032bfd29f6741ea9d56
4
+ data.tar.gz: 88bca49cea9ee2abac2d2dc9d608a33329ad9e214d57035424e8e24984691537
5
5
  SHA512:
6
- metadata.gz: 4ca381e6bcbf74d21a23ae825ebb6556be1afbe98c193fb33e58ef7fee6027142a809ed79b8cbcb3c8dce95200b0bd4528d497597a1f0411f703172ce1f9c123
7
- data.tar.gz: 945faf0852d9ebce259e4da1bcebd079ef5a4fad87f503fc9ee694f4eae7e3ab36a7dc2390d54879a7da57d176aa22d8030a168d2715fe1f54a521b2258fbb37
6
+ metadata.gz: 67dd2ada55ac862b2d57ddf893e7408d002c40c2f89a141e6bf8c115d6eeee32d19b156e7668751f591665f948fa04d628719e5f6f5ab9e4609c02f0a14a93f4
7
+ data.tar.gz: 54ded7bb163e4a38cd3fa4a62dfe101484b98e87c016514b985190f77a07c7556e980dd8574dc5fb70cacb3fcc521a37a1f4f2325e5360cdbb2ddd6f38816804
@@ -10,27 +10,28 @@ module InsightsCloud::Api
10
10
 
11
11
  skip_after_action :log_response_body, :only => [:forward_request]
12
12
  skip_before_action :check_media_type, :only => [:forward_request]
13
+ after_action :update_host_insights_status, only: [:forward_request]
13
14
 
14
15
  # The method that "proxies" requests over to Cloud
15
16
  def forward_request
16
17
  certs = candlepin_id_cert @organization
17
- cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs)
18
+ @cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs)
18
19
 
19
- if cloud_response.code == 401
20
+ if @cloud_response.code == 401
20
21
  return render json: {
21
22
  :message => 'Authentication to the Insights Service failed.',
22
23
  :headers => {},
23
24
  }, status: :bad_gateway
24
25
  end
25
26
 
26
- if cloud_response.headers[:content_disposition]
27
- return send_data cloud_response, disposition: cloud_response.headers[:content_disposition], type: cloud_response.headers[:content_type]
27
+ if @cloud_response.headers[:content_disposition]
28
+ return send_data @cloud_response, disposition: @cloud_response.headers[:content_disposition], type: @cloud_response.headers[:content_type]
28
29
  end
29
30
 
30
- assign_header(response, cloud_response, :x_resource_count, true)
31
- assign_header(response, cloud_response, :x_rh_insights_request_id, false)
31
+ assign_header(response, @cloud_response, :x_resource_count, true)
32
+ assign_header(response, @cloud_response, :x_rh_insights_request_id, false)
32
33
 
33
- render json: cloud_response, status: cloud_response.code
34
+ render json: @cloud_response, status: @cloud_response.code
34
35
  end
35
36
 
36
37
  def branch_info
@@ -69,5 +70,14 @@ module InsightsCloud::Api
69
70
  @branch_id = cp_owner_id(@organization)
70
71
  return render_message "Branch ID not found for organization #{@organization.title}", :status => 400 unless @branch_id
71
72
  end
73
+
74
+ def update_host_insights_status
75
+ return unless request.path == '/redhat_access/r/insights/platform/ingress/v1/upload' ||
76
+ request.path.include?('/redhat_access/r/insights/uploads/')
77
+
78
+ data = @cloud_response.code.to_s.start_with?('2')
79
+ host_status = @host.get_status(InsightsClientReportStatus)
80
+ host_status.update(reported_at: Time.now.utc, status: host_status.to_status(data: data))
81
+ end
72
82
  end
73
83
  end
@@ -0,0 +1,58 @@
1
+ class InsightsClientReportStatus < HostStatus::Status
2
+ REPORT_INTERVAL = 48.hours
3
+
4
+ REPORTING = 0 # host_registration_insights = true & getting data
5
+ NO_REPORT = 1 # host_registration_insights = true & not getting data
6
+ NOT_MANAGED = 2 # host_registration_insights = false
7
+ NOT_MANAGED_WITH_DATA = 3 # host_registration_insights = false & getting data
8
+
9
+ def self.status_name
10
+ N_('Insights')
11
+ end
12
+
13
+ def to_label(_options = {})
14
+ case status
15
+ when REPORTING
16
+ N_('Reporting')
17
+ when NO_REPORT
18
+ N_('Not reporting')
19
+ when NOT_MANAGED
20
+ N_('Not reporting (not set by registration)')
21
+ when NOT_MANAGED_WITH_DATA
22
+ N_('Reporting (not set by registration)')
23
+ end
24
+ end
25
+
26
+ def to_global(_options = {})
27
+ case status
28
+ when REPORTING
29
+ ::HostStatus::Global::OK
30
+ when NO_REPORT
31
+ ::HostStatus::Global::ERROR
32
+ when NOT_MANAGED
33
+ ::HostStatus::Global::OK
34
+ when NOT_MANAGED_WITH_DATA
35
+ ::HostStatus::Global::WARN
36
+ end
37
+ end
38
+
39
+ def to_status(data: false)
40
+ if insights_param
41
+ return REPORTING if data
42
+ return in_interval? ? REPORTING : NO_REPORT
43
+ end
44
+
45
+ data ? NOT_MANAGED_WITH_DATA : NOT_MANAGED
46
+ end
47
+
48
+ private
49
+
50
+ def in_interval?
51
+ return false unless reported_at
52
+ (Time.now.utc - reported_at).to_i < REPORT_INTERVAL.to_i
53
+ end
54
+
55
+ def insights_param
56
+ host.host_params_hash.dig('host_registration_insights', :value)
57
+ end
58
+ end
@@ -0,0 +1,9 @@
1
+ module ForemanRhCloud
2
+ class InsightsSubscriber < ::Foreman::BaseSubscriber
3
+ def call(*args)
4
+ host = args.first.payload[:object]
5
+ host_status = host.get_status(InsightsClientReportStatus)
6
+ host_status.update(status: host_status.to_status)
7
+ end
8
+ end
9
+ end
@@ -85,7 +85,7 @@ module ForemanInventoryUpload
85
85
  @stream.object do
86
86
  @stream.simple_field('namespace', namespace)
87
87
  @stream.simple_field('key', key)
88
- @stream.simple_field('value', value, :last)
88
+ @stream.simple_field('value', value.to_s, :last)
89
89
  end
90
90
  @stream.comma unless last
91
91
  end
@@ -78,7 +78,10 @@ module ForemanRhCloud
78
78
 
79
79
  register_global_js_file 'global'
80
80
 
81
- register_custom_status(InventorySync::InventoryStatus)
81
+ register_custom_status InventorySync::InventoryStatus
82
+ register_custom_status InsightsClientReportStatus
83
+
84
+ subscribe 'host_created.event.foreman', ForemanRhCloud::InsightsSubscriber
82
85
 
83
86
  extend_page 'hosts/show' do |context|
84
87
  context.add_pagelet :main_tabs,
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '3.0.21.1'.freeze
2
+ VERSION = '4.0.21.1'.freeze
3
3
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "3.0.21.1",
3
+ "version": "4.0.21.1",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,6 +1,9 @@
1
1
  require 'test_helper'
2
+ require 'foreman_tasks/test_helpers'
2
3
 
3
4
  class InsightsFullSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
4
7
  setup do
5
8
  InsightsCloud::Async::InsightsFullSync.any_instance.stubs(:plan_rules_sync)
6
9
  InsightsCloud::Async::InsightsFullSync.any_instance.stubs(:plan_notifications)
@@ -1,6 +1,9 @@
1
1
  require 'test_helper'
2
+ require 'foreman_tasks/test_helpers'
2
3
 
3
4
  class InsightsResolutionsSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
4
7
  setup do
5
8
  @resolutions = {
6
9
  "advisor:ansible_deprecated_repo|ANSIBLE_DEPRECATED_REPO" => {
@@ -1,6 +1,9 @@
1
1
  require 'test_helper'
2
+ require 'foreman_tasks/test_helpers'
2
3
 
3
4
  class InsightsRulesSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
4
7
  setup do
5
8
  rules_json = <<-'RULES_JSON'
6
9
  {
@@ -1,6 +1,9 @@
1
1
  require 'test_plugin_helper'
2
+ require 'foreman_tasks/test_helpers'
2
3
 
3
4
  class InventoryFullSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
4
7
  setup do
5
8
  User.current = User.find_by(login: 'secret_admin')
6
9
 
@@ -0,0 +1,77 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class InsightsClientReportStatusTest < ActiveSupport::TestCase
4
+ describe 'to_status' do
5
+ let(:host) { FactoryBot.create(:host, :managed) }
6
+
7
+ setup do
8
+ CommonParameter.where(name: 'host_registration_insights').destroy_all
9
+ end
10
+
11
+ test 'host_registration_insights = true & is getting data' do
12
+ FactoryBot.create(:common_parameter, name: 'host_registration_insights', key_type: 'boolean', value: true)
13
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
14
+
15
+ assert_equal 0, host_status.to_status(data: true)
16
+ end
17
+
18
+ test 'host_registration_insights = true & no data in less than 48 hours' do
19
+ FactoryBot.create(:common_parameter, name: 'host_registration_insights', key_type: 'boolean', value: true)
20
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
21
+ host_status.update(reported_at: 1.day.ago)
22
+ assert_equal 0, host_status.to_status
23
+ end
24
+
25
+ test 'host_registration_insights = true & no data in more than 48 hours' do
26
+ FactoryBot.create(:common_parameter, name: 'host_registration_insights', key_type: 'boolean', value: true)
27
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
28
+ host_status.update(reported_at: 3.days.ago)
29
+ assert_equal 1, host_status.to_status
30
+ end
31
+
32
+ test 'host_registration_insights = false & no data' do
33
+ FactoryBot.create(:common_parameter, name: 'host_registration_insights', key_type: 'boolean', value: false)
34
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
35
+ assert_equal 2, host_status.to_status
36
+ end
37
+
38
+ test 'host_registration_insights = false & getting data' do
39
+ FactoryBot.create(:common_parameter, name: 'host_registration_insights', key_type: 'boolean', value: false)
40
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
41
+ assert_equal 3, host_status.to_status(data: true)
42
+ end
43
+
44
+ test 'host_registration_insights = nil & is getting data' do
45
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
46
+ assert_equal 3, host_status.to_status(data: true)
47
+ end
48
+
49
+ test 'host_registration_insights = nil & no data in less than 48 hours' do
50
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
51
+ host_status.update(reported_at: 1.day.ago)
52
+ assert_equal 2, host_status.to_status
53
+ end
54
+
55
+ test 'host_registration_insights = nil & no data in more than 48 hours' do
56
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
57
+ host_status.update(reported_at: 3.days.ago)
58
+ assert_equal 2, host_status.to_status
59
+ end
60
+
61
+ test 'override param on host level from `false` to `true`' do
62
+ FactoryBot.create(:common_parameter, name: 'host_registration_insights', key_type: 'boolean', value: false)
63
+ FactoryBot.create(:host_parameter, name: 'host_registration_insights', key_type: 'boolean', value: true, host: host)
64
+
65
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
66
+ assert_equal 0, host_status.to_status(data: true)
67
+ end
68
+
69
+ test 'override param on host level from `true` to `false`' do
70
+ FactoryBot.create(:common_parameter, name: 'host_registration_insights', key_type: 'boolean', value: true)
71
+ FactoryBot.create(:host_parameter, name: 'host_registration_insights', key_type: 'boolean', value: false, host: host)
72
+
73
+ host_status = Host.find_by_name(host.name).reload.get_status(InsightsClientReportStatus)
74
+ assert_equal 2, host_status.to_status
75
+ end
76
+ end
77
+ end
@@ -296,6 +296,13 @@ class SliceGeneratorTest < ActiveSupport::TestCase
296
296
  @host.hostgroup = hostgroup
297
297
  @host.save!
298
298
 
299
+ ForemanInventoryUpload::Generators::Tags.any_instance.expects(:generate_parameters).returns(
300
+ [
301
+ ['bool_param', true],
302
+ ['int_param', 1],
303
+ ]
304
+ )
305
+
299
306
  Foreman.expects(:instance_id).twice.returns('satellite-id')
300
307
  batch = Host.where(id: @host.id).in_batches.first
301
308
  generator = create_generator(batch)
@@ -316,6 +323,8 @@ class SliceGeneratorTest < ActiveSupport::TestCase
316
323
  assert_tag(@host.location.name, actual_host, 'location')
317
324
  assert_tag(@host.organization.name, actual_host, 'organization')
318
325
  assert_tag(@host.hostgroup.name, actual_host, 'hostgroup')
326
+ assert_tag('true', actual_host, 'bool_param', 'satellite_parameter')
327
+ assert_tag('1', actual_host, 'int_param', 'satellite_parameter')
319
328
 
320
329
  assert_equal false, satellite_facts['is_hostname_obfuscated']
321
330
 
@@ -632,8 +641,8 @@ class SliceGeneratorTest < ActiveSupport::TestCase
632
641
  generator
633
642
  end
634
643
 
635
- def assert_tag(expected_value, host, tag_id)
636
- actual_tag = host['tags'].find { |tag| tag['namespace'] == 'satellite' && tag['key'] == tag_id }
644
+ def assert_tag(expected_value, host, tag_id, namespace = 'satellite')
645
+ actual_tag = host['tags'].find { |tag| tag['namespace'] == namespace && tag['key'] == tag_id }
637
646
  assert_not_nil actual_tag
638
647
  assert_equal expected_value, actual_tag['value']
639
648
  end
@@ -12,7 +12,7 @@ const FullScreenModal = ({
12
12
  terminalProps,
13
13
  }) => (
14
14
  <Modal
15
- id="full-screen-terminal"
15
+ id="rh-cloud-inventory-full-screen-terminal"
16
16
  show={showFullScreen}
17
17
  onHide={toggleFullScreen}
18
18
  >
@@ -8,7 +8,7 @@ exports[`FullScreenModal rendering render without Props 1`] = `
8
8
  bsClass="modal"
9
9
  dialogComponentClass={[Function]}
10
10
  enforceFocus={true}
11
- id="full-screen-terminal"
11
+ id="rh-cloud-inventory-full-screen-terminal"
12
12
  keyboard={true}
13
13
  manager={
14
14
  ModalManager {
@@ -1,21 +1,19 @@
1
- .rh-cloud-inventory-page {
2
- #full-screen-terminal {
3
- .modal-dialog {
4
- width: 95%;
5
- height: 95%;
6
- margin: 30px 0 0 30px;
1
+ #rh-cloud-inventory-full-screen-terminal {
2
+ .modal-dialog {
3
+ width: 95%;
4
+ height: 95%;
5
+ margin: 30px 0 0 30px;
7
6
 
8
- .modal-body {
9
- padding: 0;
10
- display: flex;
11
- height: -webkit-fill-available;
12
- height: -moz-available;
13
- height: fill-available;
7
+ .modal-body {
8
+ padding: 0;
9
+ display: flex;
10
+ height: -webkit-fill-available;
11
+ height: -moz-available;
12
+ height: fill-available;
14
13
 
15
- .terminal {
16
- margin: 0 -20px;
17
- height: 100%;
18
- }
14
+ .rh-cloud-inventory-terminal {
15
+ margin: 0 -20px;
16
+ height: 100%;
19
17
  }
20
18
  }
21
19
  }
@@ -72,7 +72,7 @@ class Terminal extends React.Component {
72
72
  return (
73
73
  <Grid.Col sm={12}>
74
74
  <div
75
- className="terminal"
75
+ className="rh-cloud-inventory-terminal"
76
76
  ref={this.terminal}
77
77
  onScroll={this.handleScroll}
78
78
  >
@@ -29,6 +29,6 @@ describe('Terminal', () => {
29
29
  const text = 'some-string-log';
30
30
  const modifiedProps = { ...props, logs: text };
31
31
  const wrapper = mount(<Terminal {...modifiedProps} />);
32
- expect(wrapper.find('.terminal p').text()).toEqual(text);
32
+ expect(wrapper.find('.rh-cloud-inventory-terminal p').text()).toEqual(text);
33
33
  });
34
34
  });
@@ -7,7 +7,7 @@ exports[`Terminal rendering render with props 1`] = `
7
7
  sm={12}
8
8
  >
9
9
  <div
10
- className="terminal"
10
+ className="rh-cloud-inventory-terminal"
11
11
  onScroll={[Function]}
12
12
  >
13
13
  <Grid
@@ -65,7 +65,7 @@ exports[`Terminal rendering render without Props 1`] = `
65
65
  sm={12}
66
66
  >
67
67
  <div
68
- className="terminal"
68
+ className="rh-cloud-inventory-terminal"
69
69
  onScroll={[Function]}
70
70
  >
71
71
  <Grid
@@ -1,34 +1,32 @@
1
- .rh-cloud-inventory-page {
2
- .terminal {
3
- height: 200px;
4
- background-color: #222;
5
- padding: 10px 0;
6
- margin-bottom: 20px;
7
- overflow-y: scroll;
8
- overflow-x: hidden;
1
+ .rh-cloud-inventory-terminal {
2
+ height: 200px;
3
+ background-color: #222;
4
+ padding: 10px 0;
5
+ margin-bottom: 20px;
6
+ overflow-y: scroll;
7
+ overflow-x: hidden;
9
8
 
10
- p {
11
- font-family: monospace;
12
- font-size: 16px;
13
- color: #22da26;
14
- overflow-wrap: anywhere;
9
+ p {
10
+ font-family: monospace;
11
+ font-size: 16px;
12
+ color: #22da26;
13
+ overflow-wrap: anywhere;
15
14
 
16
- &.terminal_error {
17
- color: #f00;
18
- }
15
+ &.terminal_error {
16
+ color: #f00;
19
17
  }
18
+ }
20
19
 
21
- &::-webkit-scrollbar {
22
- width: 12px;
23
- height: 12px;
24
- background: #aaa;
25
- }
20
+ &::-webkit-scrollbar {
21
+ width: 12px;
22
+ height: 12px;
23
+ background: #aaa;
24
+ }
26
25
 
27
- &::-webkit-scrollbar-thumb {
28
- background: #222;
29
- border-radius: 6px;
30
- border: 3px solid transparent;
31
- background-clip: content-box;
32
- }
26
+ &::-webkit-scrollbar-thumb {
27
+ background: #222;
28
+ border-radius: 6px;
29
+ border: 3px solid transparent;
30
+ background-clip: content-box;
33
31
  }
34
32
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_rh_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.21.1
4
+ version: 4.0.21.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Red Hat Cloud team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-02 00:00:00.000000000 Z
11
+ date: 2021-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: katello
@@ -160,6 +160,7 @@ files:
160
160
  - app/helpers/foreman_inventory_upload_helper.rb
161
161
  - app/helpers/foreman_inventory_upload_host_helper.rb
162
162
  - app/models/concerns/rh_cloud_host.rb
163
+ - app/models/insights_client_report_status.rb
163
164
  - app/models/insights_facet.rb
164
165
  - app/models/insights_hit.rb
165
166
  - app/models/insights_resolution.rb
@@ -174,6 +175,7 @@ files:
174
175
  - app/services/foreman_rh_cloud/cloud_request_forwarder.rb
175
176
  - app/services/foreman_rh_cloud/remediations_retriever.rb
176
177
  - app/services/foreman_rh_cloud/template_renderer_helper.rb
178
+ - app/subscribers/foreman_rh_cloud/insights_subscriber.rb
177
179
  - app/views/hosts/_insights_tab.html.erb
178
180
  - app/views/job_templates/rh_cloud_remediations.erb
179
181
  - app/views/layouts/foreman_rh_cloud/application.html.erb
@@ -245,6 +247,7 @@ files:
245
247
  - test/jobs/insights_rules_sync_test.rb
246
248
  - test/jobs/inventory_full_sync_test.rb
247
249
  - test/jobs/upload_report_job_test.rb
250
+ - test/models/insights_client_report_status_test.rb
248
251
  - test/test_plugin_helper.rb
249
252
  - test/unit/archived_report_generator_test.rb
250
253
  - test/unit/fact_helpers_test.rb
@@ -666,6 +669,7 @@ test_files:
666
669
  - test/jobs/insights_rules_sync_test.rb
667
670
  - test/jobs/inventory_full_sync_test.rb
668
671
  - test/jobs/upload_report_job_test.rb
672
+ - test/models/insights_client_report_status_test.rb
669
673
  - test/test_plugin_helper.rb
670
674
  - test/unit/archived_report_generator_test.rb
671
675
  - test/unit/fact_helpers_test.rb