Skip to content

SAT-49361 - Forward Lightspeed/CLA to cloud when IoP is enabled - #1247

Merged
jeremylenz merged 1 commit into
theforeman:developfrom
dwivedipranav-dev:SAT-49361-forward-lightspeed-to-cloud-with-iop
Aug 31, 2026
Merged

jeremylenz merged 1 commit into
theforeman:developfrom
dwivedipranav-dev:SAT-49361-forward-lightspeed-to-cloud-with-iop

Conversation

@dwivedipranav-dev

@dwivedipranav-dev dwivedipranav-dev commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

What are the changes introduced in this pull request?

Fixes SAT-49361. Command Line Assistant on content hosts is proxied through /api/lightspeed. When IoP is enabled, cert_base_url points at the local IoP gateway, which does not implement Lightspeed, so CLA stops working.
Lightspeed is cloud-only. This change always forwards /api/lightspeed to https://cert.cloud.redhat.com, using cloud identity certs, cloud CA verification, and the configured HTTP proxy, even when IoP is present.
Jira: https://redhat.atlassian.net/browse/SAT-49361

Considerations taken when implementing this change?

Advisor, inventory, and other Insights platform traffic still go to IoP in IoP mode. Only Lightspeed is special-cased.

What are the testing steps for this pull request?

  • Without IoP: CLA on a content host still works
  • satellite-installer --iop-ensure present: CLA still works
  • /var/log/foreman/production.log shows Sending request to: https://cert.cloud.redhat.com/api/lightspeed/...
  • Insights advisor/vulnerability still work against IoP

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In ForemanRhCloud::CertAuth#execute_cloud_request, force_cloud is read but not deleted from params (unlike in CloudRequest), which may unintentionally propagate this internal control flag to downstream callers; consider consistently stripping it from the options hash before issuing the HTTP request.
  • The introduction of cloud_cert_base_url and cloud_proxy_string/transformed_cloud_http_proxy_string largely mirrors existing cert_base_url/proxy_string logic; consider consolidating shared URL/proxy selection logic into a single helper to reduce duplication and the risk of the two paths diverging over time.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `ForemanRhCloud::CertAuth#execute_cloud_request`, `force_cloud` is read but not deleted from `params` (unlike in `CloudRequest`), which may unintentionally propagate this internal control flag to downstream callers; consider consistently stripping it from the options hash before issuing the HTTP request.
- The introduction of `cloud_cert_base_url` and `cloud_proxy_string`/`transformed_cloud_http_proxy_string` largely mirrors existing `cert_base_url`/`proxy_string` logic; consider consolidating shared URL/proxy selection logic into a single helper to reduce duplication and the risk of the two paths diverging over time.

## Individual Comments

### Comment 1
<location path="app/services/foreman_rh_cloud/cert_auth.rb" line_range="14-16" />
<code_context>

     def execute_cloud_request(params)
       organization = params.delete(:organization)
+      force_cloud = params[:force_cloud]
       # Cache the value of with_iop_smart_proxy? to avoid multiple calls to the database
-      with_iop_smart_proxy = ForemanRhCloud.with_iop_smart_proxy?
+      with_iop_smart_proxy = ForemanRhCloud.with_iop_smart_proxy? && !force_cloud
       certs = with_iop_smart_proxy ? foreman_certificate : candlepin_id_cert(organization)
       default_params = {
</code_context>
<issue_to_address>
**issue (bug_risk):** Consider deleting :force_cloud from params to avoid leaking internal control flags into downstream request options.

In `execute_cloud_request`, `force_cloud` is read but left in `params`, unlike `CloudRequest#execute_cloud_request` where `params.delete(:force_cloud)` is used. If `params` is later merged into HTTP options or sent to external APIs, the extra `:force_cloud` key could cause compatibility issues. Mirroring the `CloudRequest` behavior by deleting `:force_cloud` here keeps the flag internal and reduces the chance of downstream bugs.
</issue_to_address>

### Comment 2
<location path="app/services/foreman_rh_cloud/cloud_request_forwarder.rb" line_range="39-41" />
<code_context>

     def execute_cloud_request(params)
       organization = params.delete(:organization)
+      force_cloud = params[:force_cloud]
       # Cache the value of with_iop_smart_proxy? to avoid multiple calls to the database
-      with_iop_smart_proxy = ForemanRhCloud.with_iop_smart_proxy?
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Use `params.delete(:force_cloud)` for consistency and to keep control flags out of the forwarded options.

Here `force_cloud` is read but left in `params`, which are later forwarded as request options. This exposes an internal routing flag as a transport option. Align with `CloudRequest#execute_cloud_request` by using `params.delete(:force_cloud)` to keep control flags out of the forwarded options and clarify intent.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread app/services/foreman_rh_cloud/cert_auth.rb
Comment thread app/services/foreman_rh_cloud/cloud_request_forwarder.rb
Comment thread app/services/foreman_rh_cloud/cloud_request_forwarder.rb Outdated
@dwivedipranav-dev
dwivedipranav-dev force-pushed the SAT-49361-forward-lightspeed-to-cloud-with-iop branch from dd15819 to 48e98a2 Compare August 21, 2026 10:26
@dwivedipranav-dev

Copy link
Copy Markdown
Contributor Author

Dear @jeremylenz

Thanks for the valuable pointers. I have tried to implement them all on this PR.

Please let me know if anything more is required from my side.

@dwivedipranav-dev

Copy link
Copy Markdown
Contributor Author

Hello @jeremylenz
Any update on this PR please ?

@jeremylenz jeremylenz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dwivedipranav-dev

Sorry for the delay in response! After some discussion it's been decided we will accept this feature, but would like it to be off by default. Let's put it behind a user-configurable Setting:

setting 'force_cla_connection',
  type: :boolean,
  default: false,
  full_name: N_('Force RHEL Lightspeed CLA connection'),
  description: N_("Forward requests to Lightspeed CLA even when in IoP mode. Ignored when IoP mode is off.")

and then gate the forwarding on Setting[:force_cla_connection] probably by adding logic in cloud_cert_base_url.

@dwivedipranav-dev
dwivedipranav-dev force-pushed the SAT-49361-forward-lightspeed-to-cloud-with-iop branch from 48e98a2 to c7612e7 Compare August 27, 2026 01:52
@dwivedipranav-dev

Copy link
Copy Markdown
Contributor Author

Thanks @jeremylenz. I added the force_cla_connection setting (default false) and gated CLA cloud forwarding on it. With IoP on, CLA stays on IoP unless an admin enables the setting.

@jeremylenz jeremylenz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, just one non-blocking comment above

@jeremylenz
jeremylenz dismissed their stale review August 27, 2026 12:46

changes addressed

@dwivedipranav-dev
dwivedipranav-dev force-pushed the SAT-49361-forward-lightspeed-to-cloud-with-iop branch from c7612e7 to a4a78d2 Compare August 28, 2026 04:13
@dwivedipranav-dev

Copy link
Copy Markdown
Contributor Author

Thanks @jeremylenz. Addressed the non-blocking comment, CertAuth now uses params.delete(:force_cloud).

@jeremylenz jeremylenz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems my suggestion broke things:

Sending request to: https://cert.cloud.redhat.com/api/lightspeed/v1/infer
09:15:47 rails.1   | 2026-08-31T09:15:47 [D|app|a95bf59e] Exception raised for request url https://cert.cloud.redhat.com/api/lightspeed/v1/infer: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
09:15:47 rails.1   | 2026-08-31T09:15:47 [W|app|a95bf59e] Cloud request failed with exception: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
09:15:47 rails.1   | 2026-08-31T09:15:47 [I|app|a95bf59e] Completed 502 Bad Gateway in 178ms (Views: 0.3ms | ActiveRecord: 20.6ms | Allocations: 52775)
# c "hi"
⁺₋+ Asking RHEL Lightspeed...
Communication error with the server: HTTPSConnectionPool(host='satellite.example.com', port=443): Max retries exceeded with url: /api/lightspeed/v1/infer (Caused by ResponseError('too many 502 error responses')). Please try again in a few minutes.

I think the solution is to have CertAuth#execute_cloud_request go back to not deleting the force_cloud param, since CloudRequest#force_cloud does that deletion. I didn't realize before that it goes thru both those codepaths, so the CloudRequest one should be the last stop in the chain.

IoP has no Lightspeed service. Forward /api/lightspeed to
cert.cloud.redhat.com only when the force_cla_connection setting is enabled.
Rename lightspeed? to lightspeed_cla? after the Insights to RH Lightspeed rename.

Signed-off-by: Pranav Dwivedi <dwivedipranav2021@gmail.com>
@dwivedipranav-dev
dwivedipranav-dev force-pushed the SAT-49361-forward-lightspeed-to-cloud-with-iop branch from a4a78d2 to e2de292 Compare August 31, 2026 13:45
@dwivedipranav-dev

Copy link
Copy Markdown
Contributor Author

Seems my suggestion broke things:

Sending request to: https://cert.cloud.redhat.com/api/lightspeed/v1/infer
09:15:47 rails.1   | 2026-08-31T09:15:47 [D|app|a95bf59e] Exception raised for request url https://cert.cloud.redhat.com/api/lightspeed/v1/infer: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
09:15:47 rails.1   | 2026-08-31T09:15:47 [W|app|a95bf59e] Cloud request failed with exception: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
09:15:47 rails.1   | 2026-08-31T09:15:47 [I|app|a95bf59e] Completed 502 Bad Gateway in 178ms (Views: 0.3ms | ActiveRecord: 20.6ms | Allocations: 52775)
# c "hi"
⁺₋+ Asking RHEL Lightspeed...
Communication error with the server: HTTPSConnectionPool(host='satellite.example.com', port=443): Max retries exceeded with url: /api/lightspeed/v1/infer (Caused by ResponseError('too many 502 error responses')). Please try again in a few minutes.

I think the solution is to have CertAuth#execute_cloud_request go back to not deleting the force_cloud param, since CloudRequest#force_cloud does that deletion. I didn't realize before that it goes thru both those codepaths, so the CloudRequest one should be the last stop in the chain.

Thanks @jeremylenz, that makes sense. CertAuth was deleting force_cloud before CloudRequest ran, so IoP CA was still used against the cloud URL and SSL verification failed.

I reverted CertAuth to params[:force_cloud]. CloudRequest still deletes the flag at the end of the chain.

@jeremylenz jeremylenz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dwivedipranav-dev!

ACK 👍

@jeremylenz
jeremylenz merged commit c542f54 into theforeman:develop Aug 31, 2026
18 checks passed
@dwivedipranav-dev

Copy link
Copy Markdown
Contributor Author

Thanks a ton @jeremylenz for your valuable suggestions and reviewing this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants