SAT-49361 - Forward Lightspeed/CLA to cloud when IoP is enabled - #1247
Conversation
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
ForemanRhCloud::CertAuth#execute_cloud_request,force_cloudis read but not deleted fromparams(unlike inCloudRequest), 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_urlandcloud_proxy_string/transformed_cloud_http_proxy_stringlargely mirrors existingcert_base_url/proxy_stringlogic; 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>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
dd15819 to
48e98a2
Compare
|
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. |
|
Hello @jeremylenz |
jeremylenz
left a comment
There was a problem hiding this comment.
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.
48e98a2 to
c7612e7
Compare
|
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. |
There was a problem hiding this comment.
Looking good, just one non-blocking comment above
c7612e7 to
a4a78d2
Compare
|
Thanks @jeremylenz. Addressed the non-blocking comment, CertAuth now uses params.delete(:force_cloud). |
jeremylenz
left a comment
There was a problem hiding this comment.
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>
a4a78d2 to
e2de292
Compare
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
left a comment
There was a problem hiding this comment.
Thanks @dwivedipranav-dev!
ACK 👍
|
Thanks a ton @jeremylenz for your valuable suggestions and reviewing this PR. |
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_urlpoints at the local IoP gateway, which does not implement Lightspeed, so CLA stops working.Lightspeed is cloud-only. This change always forwards
/api/lightspeedtohttps://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?
satellite-installer --iop-ensure present: CLA still works/var/log/foreman/production.logshowsSending request to: https://cert.cloud.redhat.com/api/lightspeed/...