foreman_rh_cloud 12.1.2 → 12.1.4

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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -5
  3. data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +33 -0
  4. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +1 -1
  5. data/app/services/foreman_rh_cloud/cert_auth.rb +9 -1
  6. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +8 -3
  7. data/app/views/api/v2/hosts/insights/base.rabl +6 -0
  8. data/db/seeds.d/200_features.rb +4 -0
  9. data/lib/foreman_inventory_upload/async/generate_report_job.rb +11 -5
  10. data/lib/foreman_inventory_upload/async/upload_report_job.rb +15 -4
  11. data/lib/foreman_inventory_upload/generators/archived_report.rb +2 -2
  12. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +65 -13
  13. data/lib/foreman_inventory_upload/generators/queries.rb +7 -5
  14. data/lib/foreman_inventory_upload/generators/slice.rb +0 -1
  15. data/lib/foreman_inventory_upload/generators/tags.rb +4 -1
  16. data/lib/foreman_inventory_upload.rb +2 -2
  17. data/lib/foreman_rh_cloud/engine.rb +31 -2
  18. data/lib/foreman_rh_cloud/version.rb +1 -1
  19. data/lib/inventory_sync/async/inventory_hosts_sync.rb +2 -0
  20. data/lib/tasks/hybrid_cloud.rake +105 -37
  21. data/lib/tasks/rh_cloud_inventory.rake +3 -2
  22. data/package.json +1 -1
  23. data/test/controllers/insights_cloud/api/cloud_request_controller_test.rb +1 -2
  24. data/test/unit/archived_report_generator_test.rb +1 -1
  25. data/test/unit/fact_helpers_test.rb +267 -2
  26. data/test/unit/rh_cloud_http_proxy_test.rb +8 -0
  27. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +19 -2
  28. data/test/unit/slice_generator_test.rb +69 -10
  29. data/test/unit/tags_generator_test.rb +1 -0
  30. data/webpack/ForemanColumnExtensions/index.js +41 -0
  31. data/webpack/global_index.js +3 -0
  32. metadata +4 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca9c35b5c31e2f8d00889ae5c4f57a3245e038f2ff106e708c9f45909e1340d2
4
- data.tar.gz: 7b151bcccb350ff1cb748aeca126656d8e7e2712e7878ea0522b7db719c6594f
3
+ metadata.gz: 7ed52afd2a65d3cc87c3ae660716ca1044af88b359f84f108cbe005c01a37a42
4
+ data.tar.gz: b00def287ae973805693edaf6b9eb13e72846992bcb7e5432073ff722458d565
5
5
  SHA512:
6
- metadata.gz: ec35e323ea4ff1e5af20ee9a6185c83f5cf43e011a1f4879d696050381265c474cbf2b1435f72f53e43c785c797f5de013513f7efbf49e19fd87b9d2c58fe279
7
- data.tar.gz: 109928813b8f2e70ee7107d44470e04fff2fad1e9fd356f2b15f7f57092bb06c003277de931c5d5dfa84a4a379de36e4e14fd7ea2898b3070d310c4c7311e5c0
6
+ metadata.gz: 3ba0a99ac74b2b311f3569cc6dee79a5043be05abdfe41ca25e36f9c4a6e1d903732e8e38ae580c01634842ec493e8ab350f0b3d04b680e032aba9e730bd1935
7
+ data.tar.gz: 147d7da2c6352b9333bf1a5c8537c1468d2246d7bd656846ff515170b7c3841c55c73ae4e7fef690c39f56d893721efa994e271b4214d154f9542e03da43c808
data/README.md CHANGED
@@ -1,18 +1,16 @@
1
1
  [![Ruby tests](https://github.com/theforeman/foreman_rh_cloud/actions/workflows/ruby_tests.yml/badge.svg)](https://github.com/theforeman/foreman_rh_cloud/actions/workflows/ruby_tests.yml)
2
2
  [![JS](https://github.com/theforeman/foreman_rh_cloud/actions/workflows/js_tests.yml/badge.svg)](https://github.com/theforeman/foreman_rh_cloud/actions/workflows/js_tests.yml)
3
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/theforeman/foreman_rh_cloud)
3
4
 
4
5
  # ForemanRhCloud
5
6
 
6
- *Introduction here*
7
-
8
7
  ## Installation
9
8
 
10
9
  See [How_to_Install_a_Plugin](http://projects.theforeman.org/projects/foreman/wiki/How_to_Install_a_Plugin)
11
10
  for how to install Foreman plugins
12
11
 
13
- ## Usage
14
-
15
- *Usage here*
12
+ ## Project overview
13
+ See our [wiki](https://deepwiki.com/theforeman/foreman_rh_cloud)
16
14
 
17
15
  ### In Satellite
18
16
 
@@ -0,0 +1,33 @@
1
+ module InsightsCloud
2
+ module PackageProfileUploadExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # This method explicitly listens on Katello actions
7
+ # rubocop:disable Rails/LexicallyScopedActionFilter
8
+ after_action :generate_host_report, only: [:upload_package_profile, :upload_profiles]
9
+ # rubocop:enable Rails/LexicallyScopedActionFilter
10
+ end
11
+
12
+ def generate_host_report
13
+ return unless ForemanRhCloud.with_local_advisor_engine?
14
+
15
+ logger.debug("Generating host-specific report for host #{@host.name}")
16
+
17
+ ForemanTasks.async_task(
18
+ ForemanInventoryUpload::Async::GenerateReportJob,
19
+ ForemanInventoryUpload.generated_reports_folder,
20
+ @host.organization_id,
21
+ false,
22
+ "id=#{@host.id}"
23
+ )
24
+
25
+ # in IoP case, the hosts are identified by the sub-man ID, and we can assume they already
26
+ # exist in the local inventory. This will also handle facet creation for new hosts.
27
+ return if @host.insights
28
+
29
+ insights_facet = @host.build_insights(uuid: @host.subscription_facet.uuid)
30
+ insights_facet.save
31
+ end
32
+ end
33
+ end
@@ -17,7 +17,7 @@ module InsightsCloud::Api
17
17
  def forward_request
18
18
  certs = candlepin_id_cert @organization
19
19
  begin
20
- @cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs)
20
+ @cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs, @host)
21
21
  rescue RestClient::Exceptions::Timeout => e
22
22
  response_obj = e.response.presence || e.exception
23
23
  return render json: { message: response_obj.to_s, error: response_obj.to_s }, status: :gateway_timeout
@@ -10,7 +10,8 @@ module ForemanRhCloud
10
10
  end
11
11
 
12
12
  def execute_cloud_request(params)
13
- certs = candlepin_id_cert(params.delete(:organization))
13
+ organization = params.delete(:organization)
14
+ certs = ForemanRhCloud.with_local_advisor_engine? ? foreman_certificate : candlepin_id_cert(organization)
14
15
  final_params = {
15
16
  ssl_client_cert: OpenSSL::X509::Certificate.new(certs[:cert]),
16
17
  ssl_client_key: OpenSSL::PKey.read(certs[:key]),
@@ -18,5 +19,12 @@ module ForemanRhCloud
18
19
 
19
20
  super(final_params)
20
21
  end
22
+
23
+ def foreman_certificate
24
+ @foreman_certificate ||= {
25
+ cert: File.read(Setting[:ssl_certificate]),
26
+ key: File.read(Setting[:ssl_priv_key]),
27
+ }
28
+ end
21
29
  end
22
30
  end
@@ -4,7 +4,7 @@ module ForemanRhCloud
4
4
  class CloudRequestForwarder
5
5
  include ForemanRhCloud::CloudRequest
6
6
 
7
- def forward_request(original_request, controller_name, branch_id, certs)
7
+ def forward_request(original_request, controller_name, branch_id, certs, host)
8
8
  forward_params = prepare_forward_params(original_request, branch_id)
9
9
  logger.debug("Request parameters for telemetry request: #{forward_params}")
10
10
 
@@ -12,14 +12,14 @@ module ForemanRhCloud
12
12
 
13
13
  logger.debug("User agent for telemetry is: #{http_user_agent original_request}")
14
14
 
15
- request_opts = prepare_request_opts(original_request, forward_payload, forward_params, certs)
15
+ request_opts = prepare_request_opts(original_request, forward_payload, forward_params, certs, host)
16
16
 
17
17
  logger.debug("Sending request to: #{request_opts[:url]}")
18
18
 
19
19
  execute_cloud_request(request_opts)
20
20
  end
21
21
 
22
- def prepare_request_opts(original_request, forward_payload, forward_params, certs)
22
+ def prepare_request_opts(original_request, forward_payload, forward_params, certs, host)
23
23
  base_params = {
24
24
  method: original_request.method,
25
25
  payload: forward_payload,
@@ -28,6 +28,7 @@ module ForemanRhCloud
28
28
  params: forward_params,
29
29
  user_agent: http_user_agent(original_request),
30
30
  content_type: original_request.media_type.presence || original_request.format.to_s,
31
+ Forwarded: prepare_forwarded_header(host),
31
32
  }
32
33
  ),
33
34
  }
@@ -105,6 +106,10 @@ module ForemanRhCloud
105
106
  headers
106
107
  end
107
108
 
109
+ def prepare_forwarded_header(host)
110
+ "for=\"_#{host.subscription_facet.uuid}\""
111
+ end
112
+
108
113
  def lightspeed?
109
114
  ->(request_path) { request_path.include? '/lightspeed' }
110
115
  end
@@ -3,3 +3,9 @@ attributes :uuid
3
3
  node :insights_hit_details do |facet|
4
4
  facet&.host&.facts('insights::hit_details')&.values&.first
5
5
  end
6
+ node :insights_hits_count do |facet|
7
+ facet.hits&.count
8
+ end
9
+ node :use_local_advisor_engine do |_facet|
10
+ ForemanRhCloud.with_local_advisor_engine?
11
+ end
@@ -0,0 +1,4 @@
1
+ ForemanRhCloud.on_prem_smart_proxy_features.each do |feature_name|
2
+ f = Feature.where(:name => feature_name).first_or_create
3
+ raise "Unable to create proxy feature: #{SeedHelper.format_errors f}" if f.nil? || f.errors.any?
4
+ end
@@ -5,18 +5,19 @@ module ForemanInventoryUpload
5
5
  "report_for_#{label}"
6
6
  end
7
7
 
8
- def plan(base_folder, organization_id, disconnected)
8
+ def plan(base_folder, organization_id, disconnected, hosts_filter = nil)
9
9
  sequence do
10
10
  super(
11
- GenerateReportJob.output_label(organization_id),
11
+ GenerateReportJob.output_label("#{organization_id}#{hosts_filter.empty? ? nil : "[#{hosts_filter.to_s.parameterize}]"}"),
12
12
  organization_id: organization_id,
13
- base_folder: base_folder
13
+ base_folder: base_folder,
14
+ hosts_filter: hosts_filter
14
15
  )
15
16
 
16
17
  plan_action(
17
18
  QueueForUploadJob,
18
19
  base_folder,
19
- ForemanInventoryUpload.facts_archive_name(organization_id),
20
+ ForemanInventoryUpload.facts_archive_name(organization_id, hosts_filter),
20
21
  organization_id,
21
22
  disconnected
22
23
  )
@@ -34,7 +35,8 @@ module ForemanInventoryUpload
34
35
  def env
35
36
  super.merge(
36
37
  'target' => base_folder,
37
- 'organization_id' => organization_id
38
+ 'organization_id' => organization_id,
39
+ 'hosts_filter' => hosts_filter
38
40
  )
39
41
  end
40
42
 
@@ -45,6 +47,10 @@ module ForemanInventoryUpload
45
47
  def organization_id
46
48
  input[:organization_id]
47
49
  end
50
+
51
+ def hosts_filter
52
+ input[:hosts_filter]
53
+ end
48
54
  end
49
55
  end
50
56
  end
@@ -33,8 +33,8 @@ module ForemanInventoryUpload
33
33
  end
34
34
 
35
35
  Tempfile.create([organization.name, '.pem']) do |cer_file|
36
- cer_file.write(rh_credentials[:cert])
37
- cer_file.write(rh_credentials[:key])
36
+ cer_file.write(certificate[:cert])
37
+ cer_file.write(certificate[:key])
38
38
  cer_file.flush
39
39
  @cer_path = cer_file.path
40
40
  super
@@ -59,8 +59,12 @@ module ForemanInventoryUpload
59
59
  env_vars
60
60
  end
61
61
 
62
- def rh_credentials
63
- @rh_credentials ||= begin
62
+ def certificate
63
+ ForemanRhCloud.with_local_advisor_engine? ? foreman_certificate : manifest_certificate
64
+ end
65
+
66
+ def manifest_certificate
67
+ @manifest_certificate ||= begin
64
68
  candlepin_id_certificate = organization.owner_details['upstreamConsumer']['idCert']
65
69
  {
66
70
  cert: candlepin_id_certificate['cert'],
@@ -69,6 +73,13 @@ module ForemanInventoryUpload
69
73
  end
70
74
  end
71
75
 
76
+ def foreman_certificate
77
+ @foreman_certificate ||= {
78
+ cert: File.read(Setting[:ssl_certificate]),
79
+ key: File.read(Setting[:ssl_priv_key]),
80
+ }
81
+ end
82
+
72
83
  def filename
73
84
  input[:filename]
74
85
  end
@@ -6,10 +6,10 @@ module ForemanInventoryUpload
6
6
  @logger = logger
7
7
  end
8
8
 
9
- def render(organization:)
9
+ def render(organization:, filter: nil)
10
10
  Dir.mktmpdir do |tmpdir|
11
11
  @logger.info "Started generating hosts report in #{tmpdir}"
12
- host_batches = ForemanInventoryUpload::Generators::Queries.for_org(organization)
12
+ host_batches = ForemanInventoryUpload::Generators::Queries.for_org(organization, hosts_query: filter || '')
13
13
  File.open(File.join(tmpdir, 'metadata.json'), 'w') do |metadata_out|
14
14
  metadata_generator = ForemanInventoryUpload::Generators::Metadata.new(metadata_out)
15
15
  metadata_generator.render do |inner_generator|
@@ -57,17 +57,39 @@ module ForemanInventoryUpload
57
57
  end
58
58
 
59
59
  def obfuscate_hostname?(host)
60
+ # Returns true if hostname obfuscation should be applied for a given host, based on hierarchy:
61
+ # 1. Global setting for hostname obfuscation.
62
+ return true if Setting[:obfuscate_inventory_hostnames]
63
+
60
64
  insights_client_setting = fact_value(host, 'insights_client::obfuscate_hostname_enabled')
61
65
  insights_client_setting = ActiveModel::Type::Boolean.new.cast(insights_client_setting)
62
- return insights_client_setting unless insights_client_setting.nil?
63
66
 
64
- Setting[:obfuscate_inventory_hostnames]
67
+ # 2. host fact reported by insights_client
68
+ # 3. if neither of the above, don't obfuscate.
69
+ insights_client_setting.nil? ? false : insights_client_setting
65
70
  end
66
71
 
67
72
  def fqdn(host)
68
- return host.fqdn unless obfuscate_hostname?(host)
69
-
70
- fact_value(host, 'insights_client::hostname') || obfuscate_fqdn(host.fqdn)
73
+ if obfuscate_hostname?(host)
74
+ # If obfuscation is enabled, attempt to retrieve an already obfuscated hostname
75
+ # from the 'insights_client::obfuscated_hostname' fact.
76
+ # Example format of `parsed_insights_array`:
77
+ # [{"original"=>"host.example.com", "obfuscated"=>"0dd449d0a027.example.com"},
78
+ # {"original"=>"satellite.example.com", "obfuscated"=>"host2.example.com"}]
79
+ begin
80
+ parsed_insights_array = JSON.parse(fact_value(host, 'insights_client::obfuscated_hostname') || '[]')
81
+ rescue JSON::ParserError
82
+ parsed_insights_array = []
83
+ end
84
+ # Obfuscate using the following hierarchy:
85
+ # 1. the obfuscated_hostname fact sent by insights_client
86
+ parsed_insights_item = parsed_insights_array.find { |item| item['original'] == host.fqdn }
87
+ # 2. our own helper method
88
+ parsed_insights_item&.[]('obfuscated') || obfuscate_fqdn(host.fqdn)
89
+ else
90
+ # If hostname obfuscation is not enabled for this host, return the host's original FQDN.
91
+ host.fqdn
92
+ end
71
93
  end
72
94
 
73
95
  def obfuscate_fqdn(fqdn)
@@ -75,35 +97,65 @@ module ForemanInventoryUpload
75
97
  end
76
98
 
77
99
  def obfuscate_ips?(host)
78
- insights_client_setting = fact_value(host, 'insights_client::obfuscate_ip_enabled')
79
- insights_client_setting = ActiveModel::Type::Boolean.new.cast(insights_client_setting)
80
- return insights_client_setting unless insights_client_setting.nil?
100
+ # Returns true if IP obfuscation should be applied for a given host, based on hierarchy:
101
+ # 1. Global setting for IP obfuscation.
102
+ return true if Setting[:obfuscate_inventory_ips]
81
103
 
82
- Setting[:obfuscate_inventory_ips]
104
+ insights_client_ipv4_setting = fact_value(host, 'insights_client::obfuscate_ipv4_enabled')
105
+ insights_client_ipv6_setting = fact_value(host, 'insights_client::obfuscate_ipv6_enabled')
106
+
107
+ cast_ipv4_setting = ActiveModel::Type::Boolean.new.cast(insights_client_ipv4_setting)
108
+ cast_ipv6_setting = ActiveModel::Type::Boolean.new.cast(insights_client_ipv6_setting)
109
+
110
+ # 2. The host's IPv4 or IPv6 obfuscation fact value is true
111
+ # 3. If neither of the above, don't obfuscate.
112
+ cast_ipv4_setting || cast_ipv6_setting || false
83
113
  end
84
114
 
85
115
  def host_ips(host)
116
+ # Determines and returns the IP addresses associated with a host, applying obfuscation if enabled.
117
+
118
+ # If IP obfuscation is enabled for the host return a representation of obfuscated IP addresses.
86
119
  return obfuscated_ips(host) if obfuscate_ips?(host)
87
120
 
88
- # return a pass through proxy hash in case no obfuscation needed
121
+ # If IP obfuscation is NOT needed, return a special kind of Hash.
122
+ # where when you try to access a key in it
123
+ # if the key doesn't exist, it simply returns the key itself.
124
+ # This is useful because it means if you try to get an IP from this hash,
125
+ # you'll just get the original IP back. It allows the calling code to
126
+ # use the same interface whether obfuscation is applied or not.
89
127
  Hash.new { |h, k| k }
90
128
  end
91
129
 
92
130
  def obfuscated_ips(host)
93
- insights_client_ips = JSON.parse(fact_value(host, 'insights_client::ips') || '[]')
131
+ # Example format of `parsed_insights_array`:
132
+ # [{"original": "192.168.1.10", "obfuscated": "10.230.230.1"},
133
+ # {"original": "192.168.1.11", "obfuscated": "10.230.230.2"}]
134
+ begin
135
+ parsed_insights_array = JSON.parse(fact_value(host, 'insights_client::obfuscated_ipv4') || '[]')
136
+ rescue JSON::ParserError
137
+ parsed_insights_array = []
138
+ end
94
139
 
140
+ # Create a new Hash to store the mapping from original IP addresses to their obfuscated versions.
141
+ # where the 'original' IP is the key and the 'obfuscated' IP is the value.
95
142
  obfuscated_ips = Hash[
96
- insights_client_ips.map { |ip_record| [ip_record['original'], ip_record['obfuscated']] }
143
+ parsed_insights_array.map { |ip_record| [ip_record['original'], ip_record['obfuscated']] }
97
144
  ]
98
145
 
146
+ # Sets a default proc for the obfuscated_ips hash.
147
+ # When a key is accessed that does not exist in the hash, this proc is called.
148
+ # It assigns the result of obfuscate_ip(key, hash) to the missing key in the hash.
149
+ # This ensures that any missing IP address key will be obfuscated and stored automatically.
99
150
  obfuscated_ips.default_proc = proc do |hash, key|
100
151
  hash[key] = obfuscate_ip(key, hash)
101
152
  end
102
-
103
153
  obfuscated_ips
104
154
  end
105
155
 
106
156
  def obfuscate_ip(ip, ips_dict)
157
+ # Produce a new, unique obfuscated IP that is
158
+ # numerically one greater than the highest existing obfuscated IP
107
159
  max_obfuscated = ips_dict.values.map { |v| IPAddr.new(v).to_i }.max || IPAddr.new('10.230.230.0').to_i
108
160
 
109
161
  IPAddr.new(max_obfuscated + 1, Socket::AF_INET).to_s
@@ -26,9 +26,11 @@ module ForemanInventoryUpload
26
26
  'dmi::system::product_name',
27
27
  'dmi::chassis::asset_tag',
28
28
  'insights_client::obfuscate_hostname_enabled',
29
- 'insights_client::obfuscate_ip_enabled',
30
- 'insights_client::hostname',
31
- 'insights_client::ips',
29
+ 'insights_client::obfuscate_ipv4_enabled',
30
+ 'insights_client::obfuscate_ipv6_enabled',
31
+ 'insights_client::obfuscated_ipv4',
32
+ 'insights_client::obfuscated_ipv6',
33
+ 'insights_client::obfuscated_hostname',
32
34
  'insights_id',
33
35
  'conversions::activity',
34
36
  'conversions::packages::0::nevra',
@@ -58,8 +60,8 @@ module ForemanInventoryUpload
58
60
  )
59
61
  end
60
62
 
61
- def self.for_org(organization_id, use_batches: true)
62
- base_query = for_slice(Host.unscoped.where(organization_id: organization_id))
63
+ def self.for_org(organization_id, use_batches: true, hosts_query: '')
64
+ base_query = for_slice(Host.unscoped.where(organization_id: organization_id).search_for(hosts_query))
63
65
  use_batches ? base_query.in_batches(of: ForemanInventoryUpload.slice_size) : base_query
64
66
  end
65
67
  end
@@ -190,7 +190,6 @@ module ForemanInventoryUpload
190
190
  ) { |v| os_release_value(*v) }
191
191
  @stream.simple_field('os_kernel_version', fact_value(host, 'uname::release'))
192
192
  @stream.simple_field('arch', host.architecture&.name)
193
- @stream.simple_field('katello_agent_running', false)
194
193
  @stream.simple_field(
195
194
  'infrastructure_type',
196
195
  ActiveModel::Type::Boolean.new.cast(fact_value(host, 'virt::is_guest')) ? 'virtual' : 'physical'
@@ -41,7 +41,10 @@ module ForemanInventoryUpload
41
41
  end
42
42
 
43
43
  def organizations
44
- [['organization', @host.organization.name]]
44
+ [
45
+ ['organization', @host.organization.name],
46
+ ['organization_label', @host.organization.label],
47
+ ]
45
48
  end
46
49
 
47
50
  def content_data
@@ -52,8 +52,8 @@ module ForemanInventoryUpload
52
52
  'uploader.sh'
53
53
  end
54
54
 
55
- def self.facts_archive_name(organization)
56
- "report_for_#{organization}.tar.xz"
55
+ def self.facts_archive_name(organization, filter = nil)
56
+ "report_for_#{organization}#{filter.empty? ? nil : "[#{filter.to_s.parameterize}]"}.tar.xz"
57
57
  end
58
58
 
59
59
  def self.upload_url
@@ -114,8 +114,7 @@ module ForemanRhCloud
114
114
  caption: N_('Inventory Upload'),
115
115
  url: '/foreman_rh_cloud/inventory_upload',
116
116
  url_hash: { controller: :react, action: :index },
117
- parent: :insights_menu,
118
- if: -> { !ForemanRhCloud.with_local_advisor_engine? }
117
+ parent: :insights_menu
119
118
  menu :top_menu, :insights_hits, caption: N_('Recommendations'), url: '/foreman_rh_cloud/insights_cloud', url_hash: { controller: :react, action: :index }, parent: :insights_menu
120
119
  menu :top_menu,
121
120
  :insights_vulnerability,
@@ -165,6 +164,8 @@ module ForemanRhCloud
165
164
  ::Katello::UINotifications::Subscriptions::ManifestImportSuccess.include ForemanInventoryUpload::Notifications::ManifestImportSuccessNotificationOverride if defined?(Katello)
166
165
 
167
166
  ::Host::Managed.include RhCloudHost
167
+
168
+ ::Katello::Api::Rhsm::CandlepinDynflowProxyController.include InsightsCloud::PackageProfileUploadExtensions
168
169
  end
169
170
  end
170
171
 
@@ -210,6 +211,30 @@ module ForemanRhCloud
210
211
  )
211
212
  end
212
213
 
214
+ # Ideally this code belongs to an initializer. The problem is that Katello controllers are not initialized completely until after the end of the to_prepare blocks
215
+ # This means I can patch the controller only in the after_initialize block that is promised to run after the to_prepare
216
+ # initializer 'foreman_rh_cloud.allow_smart_proxy_actions', :before => :finisher_hook, :after => 'katello.register_plugin' do |_app|
217
+ # end
218
+ config.after_initialize do
219
+ # skip overrides in migrations, since the controller initialization depends on tables existense
220
+ if defined?(Katello) && !Foreman.in_setup_db_rake?
221
+ Katello::Api::V2::OrganizationsController.include Foreman::Controller::SmartProxyAuth
222
+ # patch the callbacks order for :download_debug_certificate, since local_find_taxonomy has to run after the user is already initialized
223
+ Katello::Api::V2::OrganizationsController.skip_before_action(:local_find_taxonomy, only: :download_debug_certificate)
224
+ Katello::Api::V2::OrganizationsController.add_smart_proxy_filters(
225
+ [:index, :download_debug_certificate],
226
+ features: ForemanRhCloud.on_prem_smart_proxy_features
227
+ )
228
+ Katello::Api::V2::OrganizationsController.before_action(:local_find_taxonomy, only: :download_debug_certificate)
229
+
230
+ Katello::Api::V2::RepositoriesController.include Foreman::Controller::SmartProxyAuth
231
+ Katello::Api::V2::RepositoriesController.add_smart_proxy_filters(
232
+ :index,
233
+ features: ForemanRhCloud.on_prem_smart_proxy_features
234
+ )
235
+ end
236
+ end
237
+
213
238
  rake_tasks do
214
239
  Rake::Task['db:seed'].enhance do
215
240
  ForemanRhCloud::Engine.load_seed
@@ -231,4 +256,8 @@ module ForemanRhCloud
231
256
  ::SETTINGS[:ssl_ca_file]
232
257
  end
233
258
  end
259
+
260
+ def self.on_prem_smart_proxy_features
261
+ ['Insights']
262
+ end
234
263
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '12.1.2'.freeze
2
+ VERSION = '12.1.4'.freeze
3
3
  end
@@ -8,6 +8,8 @@ module InventorySync
8
8
  set_callback :step, :around, :create_missing_hosts
9
9
 
10
10
  def plan(organizations)
11
+ # Do not run for local advisor, since we use sub-man id to identify hosts.
12
+ return if ForemanRhCloud.with_local_advisor_engine?
11
13
  # by default the tasks will be executed concurrently
12
14
  super(organizations)
13
15
  plan_self_host_sync