Skip to content

Fixes #39330 - Remove deprecated CV/LCE params from hosts, AKs, hostgroups#11753

Merged
jeremylenz merged 2 commits into
Katello:masterfrom
jeremylenz:sat-38100-remove-deprecated-cv-lce-params
May 28, 2026
Merged

Fixes #39330 - Remove deprecated CV/LCE params from hosts, AKs, hostgroups#11753
jeremylenz merged 2 commits into
Katello:masterfrom
jeremylenz:sat-38100-remove-deprecated-cv-lce-params

Conversation

@jeremylenz
Copy link
Copy Markdown
Member

@jeremylenz jeremylenz commented May 15, 2026

What are the changes introduced in this pull request?

Related PR in foreman-ansible-modules: theforeman/foreman-ansible-modules#1977

Remove the deprecated separate content_view_id and lifecycle_environment_id API parameters from hosts, activation keys, and hostgroups, in favor of content_view_environment_ids (hosts/AKs) and content_view_environment_id (hostgroups).

Also removes assign_single_environment from both ContentFacet and ActivationKey, replacing it with ContentViewEnvironment.find_by_cv_and_lce! lookups. Removes the check_cve_attributes / attributes= / update overrides on HostManagedExtensions that handled the deprecated params. Updates the host ERB form to use a content view environment dropdown instead of separate LCE/CV cascading selects. Updates content_facet_ignore_update? to gate on content_view_environment_ids instead of the removed params.

Considerations taken when implementing this change?

The ERB host form, ContentFacet.inherited_attributes, and ContentFacet#initialize all used the deprecated params together. The hidden fields in the ERB form blocked ||= in inherited_attributes from injecting hostgroup values. All three had to move to content_view_environment_ids together to avoid breaking host create/edit inheritance.

What are the testing steps for this pull request?

  • Create a host with a hostgroup that has a content view environment set — verify the content view environment is inherited/pre-populated on the host form
  • Edit an existing host — verify the content view environment is preserved and not overwritten
  • Edit a multi-content-view-environment host — verify all content view environments are preserved
  • Create/edit a hostgroup with a content view environment
  • Create an activation key via API using content_view_environment_ids:
    curl -u admin:changeme -H 'Content-Type: application/json' \
      -X POST https://$(hostname)/katello/api/v2/activation_keys \
      -d '{"organization_id": 1, "name": "test-ak", "content_view_environment_ids": [<id>]}'
    
  • Update an activation key via API using content_view_environment_ids:
    curl -u admin:changeme -H 'Content-Type: application/json' \
      -X PUT https://$(hostname)/katello/api/v2/activation_keys/<id> \
      -d '{"activation_key": {"content_view_environment_ids": [<id>]}}'
    
  • Verify that the removed params (content_view_id, lifecycle_environment_id) are no longer accepted on host/AK/hostgroup create/update APIs

Summary by CodeRabbit

  • New Features

    • Unified "Content View Environment" selector for hosts and hostgroups; preserves "Inherit" and restores prior selection.
    • UI selections for content view environment, content source, architecture and OS now consistently update available installation media.
  • Bug Fixes

    • Improved dropdown refresh and organization resolution when changing content source or install medium; synced-content resets reliably.
  • Breaking Changes

    • APIs and forms now use content_view_environment_id(s); legacy single content_view/lifecycle/environment params removed.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Migrates from separate content_view + lifecycle_environment fields to ContentViewEnvironment (CVEnv): updates JS host edit UI, API params/docs, models (facets/activation keys), helpers, actions/services, views, plugin filters, validators/migrators, and tests to use CVEnv-backed params and associations.

Changes

CVEnv migration and wiring

Layer / File(s) Summary
All checkpoints (single review pass)
multiple files across app/controllers/*, app/models/*, app/helpers/*, app/assets/javascripts/*, app/lib/*, app/views/*, test/*, lib/katello/plugin.rb
Consolidates content-view + lifecycle-environment into ContentViewEnvironment (CVEnv). Replaces deprecated single-ID API params and virtual setters/getters, adds find_by_cv_and_lce!, converts factories/tests/helpers to use content_view_environment_id/content_view_environment_ids, renames internal variables/flags from cve→cvenv, and rewires the host/hostgroup edit UI and activation-key flows to use CVEnv-backed data.
  • Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Possibly related PRs

    • Katello/katello#11724: Overlap on preserving/restoring the "inherit" option metadata in refreshContentViewEnvironments.
    • Katello/katello#11723: Related refactors touching host content-facet and CVEnv handling.
    • Katello/katello#11707: Related migration toward content_view_environment_id for hostgroup content facet.
  • Suggested labels

Needs re-review

  • Suggested reviewers

    • lfu
    • jnagare-redhat
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js (1)

57-60: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Don’t key inherit-option preservation off English text.

Line 57 only keeps the first option when its label contains "Inherit" or is empty. In translated UIs that drops the inherit option after refresh, even though the option is still structurally the “blank/inherit” choice.

Suggested fix
-    if (previousInheritText && (previousInheritText.includes('Inherit') || previousInheritText === '')) {
+    if (inheritOption.length && (inheritOption.val() === '' || previousInheritDataId)) {
       var inheritOpt = $("<option />").text(previousInheritText).val('');
       if (previousInheritDataId) inheritOpt.attr('data-id', previousInheritDataId);
       select.append(inheritOpt);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js` around lines
57 - 60, The code is currently detecting the “inherit” option by checking
previousInheritText.includes('Inherit') which breaks localized UIs; change the
detection to rely on the option's value or presence of the data-id instead.
Update the condition around previousInheritText/previousInheritDataId in the
block that creates inheritOpt (variables: previousInheritText,
previousInheritDataId, inheritOpt, select) to add the option when
previousInheritText === '' or previousInheritValue === '' or when
previousInheritDataId is present, instead of testing the displayed text; ensure
you read the original option's value (not its label) to decide preservation and
preserve any data-id attribute onto inheritOpt.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js`:
- Around line 101-126: KT.hosts.getSelectedContentViewEnvironment currently
returns null when the visible `#host_content_view_environment_id` is not present
(cv_lce_disabled? case), causing KT.hosts.toggle_installation_medium to skip
refreshing; update getSelectedContentViewEnvironment to fall back to the hidden
inputs rendered on host edit pages by checking for inputs named
"content_view_environment_ids[]" (e.g. select the first hidden input or
.first()) and returning its value (or its data-id if needed) when
`#host_content_view_environment_id` and `#hostgroup_content_view_environment_id` are
absent so toggle_installation_medium receives a valid
content_view_environment_id.

In `@app/helpers/katello/hosts_and_hostgroups_helper.rb`:
- Around line 74-82: The current else branch in the host_or_hostgroup handling
unconditionally returns
host_or_hostgroup.content_facet.content_view_environments.first which can be nil
and thus prevents the selected_host_group fallback from running; update the
logic in the host_or_hostgroup branch (symbols: host_or_hostgroup,
content_facet, content_view_environments) to only return the first environment
if it is present (e.g., assign first_env =
host_or_hostgroup.content_facet.content_view_environments.first and return
first_env only when first_env.present?), otherwise allow execution to continue
so the subsequent selected_host_group (symbol: selected_host_group)
content_facet.content_view_environment fallback can run.

In `@app/models/katello/host/content_facet.rb`:
- Around line 83-87: The current initialization pulls content_view_environments
with ContentViewEnvironment.where(id: cve_ids) which silently drops missing IDs
and loses the requested order; change this to load the records into a hash keyed
by id (using ContentViewEnvironment.where(id: cve_ids).index_by(&:id)) then map
the original cve_ids array to that hash to preserve order and detect missing
records, raising a clear error (e.g., ActiveRecord::RecordNotFound or
ArgumentError) if any requested id is absent before assigning
self.content_view_environments; adjust the code around
init_args.delete(:content_view_environment_ids), cve_ids, and the assignment to
content_view_environments accordingly.

In `@app/views/overrides/activation_keys/_host_environment_select.html.erb`:
- Around line 46-49: host_cve_ids may produce multiple hidden inputs with the
same generated DOM id (from hidden_field_tag
'host[content_facet_attributes][content_view_environment_ids][]'), causing
duplicate IDs; fix by iterating with an index (host_cve_ids.each_with_index) and
pass an explicit unique id option to hidden_field_tag (e.g.
"host_content_facet_attributes_content_view_environment_ids_#{index}") or remove
the id entirely by passing id: nil so each hidden input has no duplicate id
while keeping the same name attribute.

---

Outside diff comments:
In `@app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js`:
- Around line 57-60: The code is currently detecting the “inherit” option by
checking previousInheritText.includes('Inherit') which breaks localized UIs;
change the detection to rely on the option's value or presence of the data-id
instead. Update the condition around previousInheritText/previousInheritDataId
in the block that creates inheritOpt (variables: previousInheritText,
previousInheritDataId, inheritOpt, select) to add the option when
previousInheritText === '' or previousInheritValue === '' or when
previousInheritDataId is present, instead of testing the displayed text; ensure
you read the original option's value (not its label) to decide preservation and
preserve any data-id attribute onto inheritOpt.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f88a001e-bc3c-412f-b345-191cd0d72cb7

📥 Commits

Reviewing files that changed from the base of the PR and between c0e96be and 902400c.

📒 Files selected for processing (34)
  • app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js
  • app/controllers/katello/api/v2/activation_keys_controller.rb
  • app/controllers/katello/api/v2/host_contents_controller.rb
  • app/controllers/katello/concerns/api/v2/hostgroups_controller_extensions.rb
  • app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb
  • app/helpers/katello/hosts_and_hostgroups_helper.rb
  • app/helpers/katello/kickstart_repository_helper.rb
  • app/lib/actions/katello/activation_key/reassign.rb
  • app/lib/actions/katello/host/reassign.rb
  • app/lib/actions/katello/host/update_content_view.rb
  • app/models/katello/activation_key.rb
  • app/models/katello/concerns/content_facet_host_extensions.rb
  • app/models/katello/concerns/host_managed_extensions.rb
  • app/models/katello/concerns/hostgroup_extensions.rb
  • app/models/katello/content_view_environment.rb
  • app/models/katello/host/content_facet.rb
  • app/models/katello/hostgroup/content_facet.rb
  • app/views/katello/api/v2/activation_keys/base.json.rabl
  • app/views/katello/api/v2/hostgroups_extensions/show.json.rabl
  • app/views/overrides/activation_keys/_host_environment_select.html.erb
  • lib/katello/plugin.rb
  • test/controllers/api/v2/activation_keys_controller_test.rb
  • test/controllers/api/v2/hostgroups_controller_test.rb
  • test/controllers/api/v2/hosts_controller_test.rb
  • test/factories/host_factory.rb
  • test/helpers/hosts_and_hostgroups_helper_test.rb
  • test/helpers/url_helpers_test.rb
  • test/lib/concerns/renderer_extensions_test.rb
  • test/mailers/errata_mailer_test.rb
  • test/models/concerns/content_facet_host_extensions_test.rb
  • test/models/concerns/host_managed_extensions_test.rb
  • test/models/erratum_test.rb
  • test/models/host/content_facet_test.rb
  • test/support/host_support.rb
💤 Files with no reviewable changes (4)
  • app/controllers/katello/concerns/api/v2/hostgroups_controller_extensions.rb
  • app/views/katello/api/v2/activation_keys/base.json.rabl
  • app/models/katello/activation_key.rb
  • app/models/katello/concerns/host_managed_extensions.rb

Comment thread app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js
Comment thread app/helpers/katello/hosts_and_hostgroups_helper.rb
Comment thread app/models/katello/host/content_facet.rb Outdated
Comment thread app/views/overrides/activation_keys/_host_environment_select.html.erb Outdated
@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch 3 times, most recently from 8fe71fc to 4c9512a Compare May 18, 2026 19:44
…roups

Remove the deprecated separate content_view_id and lifecycle_environment_id
API parameters that were replaced by content_view_environment_ids (hosts/AKs)
and content_view_environment_id (hostgroups) in 6.19. Since 7.0 allows
breaking changes, this fully removes the backward-compatibility layer.

Key changes:
- Remove assign_single_environment from ContentFacet and ActivationKey
  (fixes incorrect first_or_create behavior in AK version)
- Add ContentViewEnvironment.find_by_cv_and_lce! class method
- Remove check_cve_attributes and related backward-compat in HostManagedExtensions
- Simplify Hostgroup::ContentFacet by removing pending variable machinery
- Remove setter delegates from HostgroupExtensions
- Update ERB host form to use single CVEnv dropdown
- Update JS to use content_view_environment_id instead of separate cascading dropdowns
- Update parameter filters in plugin.rb
- Remove deprecated params from API controllers and RABL responses

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@nofaralfasi nofaralfasi left a comment

Choose a reason for hiding this comment

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

I noticed CI is failing HostgroupsControllerTest#test_create_with_ks_repo, and that test in test/controllers/foreman/hostgroups_controller_test.rb still posts deprecated content_view_id / lifecycle_environment_id params.
Since this PR removes those hostgroup params in favor of content_view_environment_id, should we update that test in this PR?

Comment thread app/services/katello/registration_manager.rb Outdated
Comment thread app/services/katello/registration_manager.rb
Comment thread app/models/katello/content_view_environment.rb Outdated
Comment thread app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js Outdated
Comment thread app/services/katello/registration_manager.rb
@jeremylenz
Copy link
Copy Markdown
Member Author

@nofaralfasi Updated:

  1. Fix 1: Removed extra host_uuid arg from populate_content_facet call (bad rebase merge)
  2. Fix 2: Replaced activation_key.content_view/.environment with activation_key.content_view_environments.first in lookup_content_view_environments
  3. Fix 3: Changed %s/%s to %{env}/%{cv} named placeholders for gettext
  4. Fix 4: Changed previousValue === '' to inheritOption.val() === '' for locale-safe inherit option detection
  5. Fix 5: Updated Foreman hostgroups controller test to use content_view_environment_id
  6. Fix 6: Added two tests for lookup_content_view_environments — single-CVEnv mode and error case

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/helpers/katello/content_options_helper.rb`:
- Line 77: The optgroup label interpolates org.name into HTML without escaping,
allowing XSS; update the interpolation in
app/helpers/katello/content_options_helper.rb to HTML-escape org.name before
building the string (e.g., use h(org.name) or ERB::Util.html_escape(org.name)
when constructing the "%(<optgroup label=...>#{cvenv_options}</optgroup>)"
string) so the returned html_safe output contains a safe, escaped label.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0736dbbd-3c7d-4a2c-8936-c0960220312d

📥 Commits

Reviewing files that changed from the base of the PR and between 902400c and 489455d.

📒 Files selected for processing (72)
  • app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js
  • app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
  • app/controllers/katello/api/v2/activation_keys_controller.rb
  • app/controllers/katello/api/v2/content_view_versions_controller.rb
  • app/controllers/katello/api/v2/host_contents_controller.rb
  • app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb
  • app/controllers/katello/concerns/api/v2/hostgroups_controller_extensions.rb
  • app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb
  • app/controllers/katello/concerns/authorization/api/v2/content_views_controller.rb
  • app/helpers/katello/content_options_helper.rb
  • app/helpers/katello/hosts_and_hostgroups_helper.rb
  • app/helpers/katello/kickstart_repository_helper.rb
  • app/lib/actions/katello/activation_key/reassign.rb
  • app/lib/actions/katello/content_view/add_to_environment.rb
  • app/lib/actions/katello/content_view/incremental_updates.rb
  • app/lib/actions/katello/content_view/remove.rb
  • app/lib/actions/katello/content_view/remove_from_environment.rb
  • app/lib/actions/katello/environment/destroy.rb
  • app/lib/actions/katello/host/reassign.rb
  • app/lib/actions/katello/host/update_content_view.rb
  • app/lib/actions/katello/organization/destroy.rb
  • app/lib/actions/katello/organization/environment_contents_refresh.rb
  • app/lib/katello/util/cve_hgcf_migrator.rb
  • app/lib/katello/util/cveak_migrator.rb
  • app/lib/katello/util/cvecf_migrator.rb
  • app/lib/katello/validators/generated_content_view_validator.rb
  • app/lib/katello/validators/hostgroup_kickstart_repository_validator.rb
  • app/models/katello/activation_key.rb
  • app/models/katello/authorization/repository.rb
  • app/models/katello/concerns/content_facet_host_extensions.rb
  • app/models/katello/concerns/host_managed_extensions.rb
  • app/models/katello/concerns/hostgroup_extensions.rb
  • app/models/katello/concerns/subscription_facet_host_extensions.rb
  • app/models/katello/content_view_environment.rb
  • app/models/katello/content_view_environment_activation_key.rb
  • app/models/katello/content_view_environment_content_facet.rb
  • app/models/katello/host/content_facet.rb
  • app/models/katello/host/info_provider.rb
  • app/models/katello/host/subscription_facet.rb
  • app/models/katello/hostgroup/content_facet.rb
  • app/models/katello/repository.rb
  • app/services/katello/content_view_manager.rb
  • app/services/katello/product_content_finder.rb
  • app/services/katello/registration_manager.rb
  • app/views/katello/api/v2/activation_keys/base.json.rabl
  • app/views/katello/api/v2/hostgroups_extensions/show.json.rabl
  • app/views/overrides/activation_keys/_host_environment_select.html.erb
  • developer_docs/quick_reference.md
  • lib/katello/plugin.rb
  • test/actions/katello/content_view_test.rb
  • test/actions/katello/environment_test.rb
  • test/controllers/api/v2/activation_keys_controller_test.rb
  • test/controllers/api/v2/content_views_controller_test.rb
  • test/controllers/api/v2/hostgroups_controller_test.rb
  • test/controllers/api/v2/hosts_controller_test.rb
  • test/controllers/foreman/hostgroups_controller_test.rb
  • test/factories/host_factory.rb
  • test/helpers/hosts_and_hostgroups_helper_test.rb
  • test/helpers/url_helpers_test.rb
  • test/lib/concerns/renderer_extensions_test.rb
  • test/lib/validators/hostgroup_kickstart_repository_validator_test.rb
  • test/mailers/errata_mailer_test.rb
  • test/models/activation_key_test.rb
  • test/models/concerns/content_facet_host_extensions_test.rb
  • test/models/concerns/host_managed_extensions_test.rb
  • test/models/concerns/hostgroup_extensions_test.rb
  • test/models/content_view_test.rb
  • test/models/erratum_test.rb
  • test/models/host/content_facet_test.rb
  • test/models/repository_test.rb
  • test/services/katello/registration_manager_test.rb
  • test/support/host_support.rb
💤 Files with no reviewable changes (3)
  • app/controllers/katello/concerns/api/v2/hostgroups_controller_extensions.rb
  • app/views/katello/api/v2/activation_keys/base.json.rabl
  • app/models/katello/concerns/host_managed_extensions.rb
✅ Files skipped from review due to trivial changes (16)
  • developer_docs/quick_reference.md
  • app/lib/katello/validators/generated_content_view_validator.rb
  • app/lib/actions/katello/content_view/incremental_updates.rb
  • test/models/repository_test.rb
  • app/lib/actions/katello/environment/destroy.rb
  • app/lib/actions/katello/organization/environment_contents_refresh.rb
  • app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
  • app/lib/actions/katello/content_view/add_to_environment.rb
  • app/models/katello/authorization/repository.rb
  • app/controllers/katello/api/v2/content_view_versions_controller.rb
  • app/controllers/katello/concerns/authorization/api/v2/content_views_controller.rb
  • test/actions/katello/environment_test.rb
  • app/lib/actions/katello/organization/destroy.rb
  • app/lib/katello/util/cve_hgcf_migrator.rb
  • test/models/content_view_test.rb
  • app/models/katello/host/info_provider.rb
🚧 Files skipped from review as they are similar to previous changes (23)
  • test/helpers/url_helpers_test.rb
  • test/mailers/errata_mailer_test.rb
  • test/factories/host_factory.rb
  • app/lib/actions/katello/host/update_content_view.rb
  • app/lib/actions/katello/activation_key/reassign.rb
  • app/views/katello/api/v2/hostgroups_extensions/show.json.rabl
  • app/models/katello/concerns/content_facet_host_extensions.rb
  • app/views/overrides/activation_keys/_host_environment_select.html.erb
  • app/lib/actions/katello/host/reassign.rb
  • test/models/erratum_test.rb
  • test/models/concerns/content_facet_host_extensions_test.rb
  • test/helpers/hosts_and_hostgroups_helper_test.rb
  • app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb
  • app/models/katello/hostgroup/content_facet.rb
  • app/controllers/katello/api/v2/host_contents_controller.rb
  • app/helpers/katello/hosts_and_hostgroups_helper.rb
  • test/models/host/content_facet_test.rb
  • app/models/katello/host/content_facet.rb
  • app/models/katello/content_view_environment.rb
  • test/controllers/api/v2/hosts_controller_test.rb
  • lib/katello/plugin.rb
  • test/models/concerns/host_managed_extensions_test.rb
  • test/controllers/api/v2/hostgroups_controller_test.rb

Comment thread app/helpers/katello/content_options_helper.rb Outdated
@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch 2 times, most recently from 2df53a6 to a05a66a Compare May 20, 2026 16:51
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
app/models/katello/host/content_facet.rb (1)

89-93: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve requested CVEnv order and reject unknown IDs during initialization.

Line 92 uses where(id: cvenv_ids), which can reorder results and silently ignore invalid IDs. That can produce incorrect CVEnv priority/order on initialization.

Suggested fix
       cvenv_ids = init_args.delete(:content_view_environment_ids)
       super(*args)
       if cvenv_ids.present?
-          self.content_view_environments = ContentViewEnvironment.where(id: cvenv_ids)
+          requested_ids = Array(cvenv_ids).map(&:to_s)
+          cvenvs_by_id = ContentViewEnvironment.where(id: requested_ids).index_by { |cvenv| cvenv.id.to_s }
+          missing_ids = requested_ids - cvenvs_by_id.keys
+
+          raise ActiveRecord::RecordNotFound, "Couldn't find all Katello::ContentViewEnvironment records for IDs: #{missing_ids.join(', ')}" if missing_ids.any?
+
+          self.content_view_environments = requested_ids.map { |id| cvenvs_by_id.fetch(id) }
       end
       self.cvenvs_changed = false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/models/katello/host/content_facet.rb` around lines 89 - 93, The current
init uses ContentViewEnvironment.where(id: cvenv_ids) which can reorder results
and silently ignore unknown IDs; change the init to coerce cvenv_ids to an array
of IDs and load them with ContentViewEnvironment.find(ids) (or fetch and compare
ids using index_by) so records are returned in the requested order and missing
IDs cause an error (or are explicitly rejected) before assigning
self.content_view_environments.
🧹 Nitpick comments (2)
test/controllers/api/v2/content_views_controller_test.rb (1)

656-659: ⚡ Quick win

Use a version-independent CVEnv lookup in test setup.

Line 656 ties the lookup to alternate_cv.versions.first, which is brittle if version ordering or promoted version changes; that can cascade into a nil dereference at Line 690.

Suggested fix
-      alternate_cvenv = Katello::ContentViewEnvironment.find_by(
-        :content_view_version_id => alternate_cv.versions.first.id,
-        :environment_id => alternate_env.id
-      )
+      alternate_cvenv = Katello::ContentViewEnvironment.find_by!(
+        :content_view_id => alternate_cv.id,
+        :environment_id => alternate_env.id
+      )

Also applies to: 690-690

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/controllers/api/v2/content_views_controller_test.rb` around lines 656 -
659, The test setup should not rely on a specific ContentViewVersion; replace
the brittle lookup
Katello::ContentViewEnvironment.find_by(content_view_version_id:
alternate_cv.versions.first.id, environment_id: alternate_env.id) with a
version-independent lookup that uses the content view id and environment id
(e.g. find_by(content_view_id: alternate_cv.id, environment_id:
alternate_env.id) or a where(...).first) so alternate_cvenv is resolved
regardless of promoted/version ordering (also apply the same change where the
lookup is repeated near line 690).
test/controllers/api/v2/hosts_controller_test.rb (1)

61-62: ⚡ Quick win

Use strict CVEnv lookups for clearer test failures.

These where(...).first lookups can produce nil and fail later as NoMethodError. Using find_by_cv_and_lce! makes failures immediate and explicit.

Proposed refactor
-    target_cvenv = ::Katello::ContentViewEnvironment.where(:content_view_id => `@cv3.id`,
-      :environment_id => `@dev.id`).first
+    target_cvenv = ::Katello::ContentViewEnvironment.find_by_cv_and_lce!(`@cv3.id`, `@dev.id`)
...
-    target_cvenvs = [::Katello::ContentViewEnvironment.where(:content_view_id => `@cv4.id`,
-      :environment_id => `@dev.id`).first, ::Katello::ContentViewEnvironment.where(:content_view_id => `@cv3.id`,
-      :environment_id => `@dev.id`).first]
+    target_cvenvs = [
+      ::Katello::ContentViewEnvironment.find_by_cv_and_lce!(`@cv4.id`, `@dev.id`),
+      ::Katello::ContentViewEnvironment.find_by_cv_and_lce!(`@cv3.id`, `@dev.id`),
+    ]
...
-    target_cvenvs_ids = [::Katello::ContentViewEnvironment.where(:content_view_id => `@cv4.id`,
-      :environment_id => `@dev.id`).first, ::Katello::ContentViewEnvironment.where(:content_view_id => `@cv3.id`,
-      :environment_id => `@dev.id`).first].map(&:id)
+    target_cvenvs_ids = [
+      ::Katello::ContentViewEnvironment.find_by_cv_and_lce!(`@cv4.id`, `@dev.id`).id,
+      ::Katello::ContentViewEnvironment.find_by_cv_and_lce!(`@cv3.id`, `@dev.id`).id,
+    ]

Also applies to: 83-85, 107-109

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/controllers/api/v2/hosts_controller_test.rb` around lines 61 - 62,
Replace the fragile "Katello::ContentViewEnvironment.where(...).first" lookup
used to set target_cvenv with the strict lookup method
"Katello::ContentViewEnvironment.find_by_cv_and_lce!" (passing the content view
`@cv3` and environment `@dev`) so the test raises an explicit error on missing
records; do the same for the other similar lookups in this test (the occurrences
that use where(...).first around the later assertions) to ensure failures are
immediate and clear.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/models/katello/concerns/content_facet_host_extensions.rb`:
- Line 77: The reject logic currently checks
attributes['content_view_environment_ids'].blank? which treats [""] as present;
update the reject_if condition used in content_facet_host_extensions.rb (the
reject block that inspects attributes['content_view_environment_ids']) to
normalize the param into an array and treat arrays of blank strings as empty—for
example by converting to Array(attributes['content_view_environment_ids']) and
checking that after rejecting blank entries it is empty—so that [""] is
considered blank and the reject_if behaves correctly.

In `@test/controllers/api/v2/activation_keys_controller_test.rb`:
- Around line 449-467: This test mutates Setting['allow_multiple_content_views']
and doesn't restore it; save the original value before setting it true, and
ensure you restore it at the end of the test (use an ensure/finally or test
teardown) so subsequent tests are not affected; update the test surrounding
Setting['allow_multiple_content_views'] (the block that sets it, uses multi_key
and calls put :update on the controller) to capture the original setting and
reset it after the assertions.

---

Duplicate comments:
In `@app/models/katello/host/content_facet.rb`:
- Around line 89-93: The current init uses ContentViewEnvironment.where(id:
cvenv_ids) which can reorder results and silently ignore unknown IDs; change the
init to coerce cvenv_ids to an array of IDs and load them with
ContentViewEnvironment.find(ids) (or fetch and compare ids using index_by) so
records are returned in the requested order and missing IDs cause an error (or
are explicitly rejected) before assigning self.content_view_environments.

---

Nitpick comments:
In `@test/controllers/api/v2/content_views_controller_test.rb`:
- Around line 656-659: The test setup should not rely on a specific
ContentViewVersion; replace the brittle lookup
Katello::ContentViewEnvironment.find_by(content_view_version_id:
alternate_cv.versions.first.id, environment_id: alternate_env.id) with a
version-independent lookup that uses the content view id and environment id
(e.g. find_by(content_view_id: alternate_cv.id, environment_id:
alternate_env.id) or a where(...).first) so alternate_cvenv is resolved
regardless of promoted/version ordering (also apply the same change where the
lookup is repeated near line 690).

In `@test/controllers/api/v2/hosts_controller_test.rb`:
- Around line 61-62: Replace the fragile
"Katello::ContentViewEnvironment.where(...).first" lookup used to set
target_cvenv with the strict lookup method
"Katello::ContentViewEnvironment.find_by_cv_and_lce!" (passing the content view
`@cv3` and environment `@dev`) so the test raises an explicit error on missing
records; do the same for the other similar lookups in this test (the occurrences
that use where(...).first around the later assertions) to ensure failures are
immediate and clear.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ed0b6aea-1746-46ce-9a82-9582cd8cfd85

📥 Commits

Reviewing files that changed from the base of the PR and between 489455d and a05a66a.

📒 Files selected for processing (68)
  • app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js
  • app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
  • app/controllers/katello/api/v2/activation_keys_controller.rb
  • app/controllers/katello/api/v2/content_view_versions_controller.rb
  • app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb
  • app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb
  • app/controllers/katello/concerns/authorization/api/v2/content_views_controller.rb
  • app/helpers/katello/content_options_helper.rb
  • app/helpers/katello/hosts_and_hostgroups_helper.rb
  • app/helpers/katello/kickstart_repository_helper.rb
  • app/lib/actions/katello/activation_key/reassign.rb
  • app/lib/actions/katello/content_view/add_to_environment.rb
  • app/lib/actions/katello/content_view/incremental_updates.rb
  • app/lib/actions/katello/content_view/remove.rb
  • app/lib/actions/katello/content_view/remove_from_environment.rb
  • app/lib/actions/katello/environment/destroy.rb
  • app/lib/actions/katello/host/reassign.rb
  • app/lib/actions/katello/host/update_content_view.rb
  • app/lib/actions/katello/organization/destroy.rb
  • app/lib/actions/katello/organization/environment_contents_refresh.rb
  • app/lib/katello/util/cve_hgcf_migrator.rb
  • app/lib/katello/util/cveak_migrator.rb
  • app/lib/katello/util/cvecf_migrator.rb
  • app/lib/katello/validators/generated_content_view_validator.rb
  • app/lib/katello/validators/hostgroup_kickstart_repository_validator.rb
  • app/models/katello/activation_key.rb
  • app/models/katello/authorization/repository.rb
  • app/models/katello/concerns/content_facet_host_extensions.rb
  • app/models/katello/concerns/hostgroup_extensions.rb
  • app/models/katello/concerns/subscription_facet_host_extensions.rb
  • app/models/katello/content_view_environment.rb
  • app/models/katello/content_view_environment_activation_key.rb
  • app/models/katello/content_view_environment_content_facet.rb
  • app/models/katello/host/content_facet.rb
  • app/models/katello/host/info_provider.rb
  • app/models/katello/host/subscription_facet.rb
  • app/models/katello/repository.rb
  • app/services/katello/content_view_manager.rb
  • app/services/katello/product_content_finder.rb
  • app/services/katello/registration_manager.rb
  • app/views/overrides/activation_keys/_host_environment_select.html.erb
  • developer_docs/quick_reference.md
  • test/actions/katello/content_view_test.rb
  • test/actions/katello/environment_test.rb
  • test/controllers/api/v2/activation_keys_controller_test.rb
  • test/controllers/api/v2/api_controller_test.rb
  • test/controllers/api/v2/content_views_controller_test.rb
  • test/controllers/api/v2/hostgroups_controller_test.rb
  • test/controllers/api/v2/hosts_controller_test.rb
  • test/controllers/foreman/hostgroups_controller_test.rb
  • test/factories/host_factory.rb
  • test/helpers/hosts_and_hostgroups_helper_test.rb
  • test/helpers/url_helpers_test.rb
  • test/lib/concerns/renderer_extensions_test.rb
  • test/lib/validators/hostgroup_kickstart_repository_validator_test.rb
  • test/mailers/errata_mailer_test.rb
  • test/models/activation_key_test.rb
  • test/models/authorization/activation_key_authorization_test.rb
  • test/models/concerns/content_facet_host_extensions_test.rb
  • test/models/concerns/host_managed_extensions_test.rb
  • test/models/concerns/hostgroup_extensions_test.rb
  • test/models/content_view_test.rb
  • test/models/erratum_test.rb
  • test/models/host/content_facet_test.rb
  • test/models/hostgroup/content_facet_test.rb
  • test/models/repository_test.rb
  • test/services/katello/registration_manager_test.rb
  • test/support/host_support.rb
✅ Files skipped from review due to trivial changes (16)
  • app/lib/actions/katello/environment/destroy.rb
  • app/lib/actions/katello/content_view/incremental_updates.rb
  • developer_docs/quick_reference.md
  • app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
  • app/lib/actions/katello/organization/environment_contents_refresh.rb
  • app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb
  • app/controllers/katello/concerns/authorization/api/v2/content_views_controller.rb
  • app/models/katello/host/info_provider.rb
  • app/lib/actions/katello/content_view/remove_from_environment.rb
  • app/lib/actions/katello/content_view/add_to_environment.rb
  • test/models/repository_test.rb
  • app/lib/katello/util/cveak_migrator.rb
  • app/controllers/katello/api/v2/content_view_versions_controller.rb
  • app/services/katello/product_content_finder.rb
  • app/lib/actions/katello/organization/destroy.rb
  • app/lib/katello/util/cve_hgcf_migrator.rb

Comment thread app/models/katello/concerns/content_facet_host_extensions.rb Outdated
Comment thread test/controllers/api/v2/activation_keys_controller_test.rb
@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch from a05a66a to e57599e Compare May 20, 2026 17:05
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/controllers/katello/api/v2/activation_keys_controller.rb (1)

223-233: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Blank CVEnv payloads still raise before the clear path runs.

[] and "" are truthy in Ruby, so Line 223 still calls fetch_content_view_environments for blank inputs and Line 228 can raise via handle_errors before handle_blank_cvenv_params gets a chance to clear the association. That turns a "remove all CVEnvs" update into a 4xx instead of persisting an empty set.

Proposed fix
     def find_content_view_environments
       `@content_view_environments` = []
-      if params_likely_not_from_angularjs? && (params[:content_view_environments] || params[:content_view_environment_ids])
+      handle_blank_cvenv_params
+      if params_likely_not_from_angularjs? &&
+         (params[:content_view_environments].present? || params[:content_view_environment_ids].present?)
         `@content_view_environments` = ::Katello::ContentViewEnvironment.fetch_content_view_environments(
           labels: params[:content_view_environments],
           ids: params[:content_view_environment_ids],
           organization: `@organization` || `@activation_key`&.organization)
         if `@content_view_environments.blank`?
           handle_errors(labels: params[:content_view_environments],
           ids: params[:content_view_environment_ids])
         end
       end
-      handle_blank_cvenv_params
       `@organization` ||= `@content_view_environments.first`&.organization
     end
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/controllers/katello/api/v2/activation_keys_controller.rb` around lines
223 - 233, The current conditional calls
::Katello::ContentViewEnvironment.fetch_content_view_environments when params
like params[:content_view_environments] or params[:content_view_environment_ids]
are present but blank (e.g. "" or []), causing handle_errors to raise before
handle_blank_cvenv_params can clear associations; update the condition in the
controller so it only calls fetch_content_view_environments when the params are
present and not blank (e.g. use .present? or !.blank? on
params[:content_view_environments] and params[:content_view_environment_ids])
and ensure `@content_view_environments` is only set from
fetch_content_view_environments in that non-blank case so
handle_blank_cvenv_params can run for explicit empty payloads without triggering
handle_errors.
test/controllers/api/v2/hosts_controller_test.rb (1)

77-122: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Restore Setting[:allow_multiple_content_views] after each test.

Both tests mutate a global setting without reset, which can leak state into subsequent tests.

Proposed fix
 def test_host_contents_environments_param
-  Setting[:allow_multiple_content_views] = true
+  original_allow_multiple = Setting[:allow_multiple_content_views]
+  Setting[:allow_multiple_content_views] = true
   ::Host::Managed.any_instance.stubs(:update_candlepin_associations)
   host = FactoryBot.create(:host, :with_content, :with_subscription, :with_operatingsystem,
                             :content_view => `@content_view`, :lifecycle_environment => `@environment`, :organization => `@environment.organization`)
@@
   host.content_facet.reload
   assert_equal 2, host.content_facet.content_view_environment_ids.count
   refute_equal orig_cvenvs, host.content_facet.content_view_environment_ids
   assert_equal_arrays target_cvenvs_ids, host.content_facet.content_view_environments.ids
+ensure
+  Setting[:allow_multiple_content_views] = original_allow_multiple
 end

 def test_host_contents_cvenv_ids_param
-  Setting[:allow_multiple_content_views] = true
+  original_allow_multiple = Setting[:allow_multiple_content_views]
+  Setting[:allow_multiple_content_views] = true
   ::Host::Managed.any_instance.stubs(:update_candlepin_associations)
   host = FactoryBot.create(:host, :with_content, :with_subscription, :with_operatingsystem,
                             :content_view => `@content_view`, :lifecycle_environment => `@environment`)
@@
   assert_equal 2, host.content_facet.content_view_environment_ids.count
   refute_equal orig_cvenvs, host.content_facet.content_view_environment_ids
   assert_equal_arrays target_cvenvs_ids, host.content_facet.content_view_environments.ids
+ensure
+  Setting[:allow_multiple_content_views] = original_allow_multiple
 end
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/controllers/api/v2/hosts_controller_test.rb` around lines 77 - 122,
These tests (test_host_contents_cvenv_labels_param and
test_host_contents_cvenv_ids_param) mutate the global
Setting[:allow_multiple_content_views] and do not restore it; capture the
original value before setting it to true and restore it after the test (use a
teardown/ensure block or wrap the test with save/restore) so subsequent tests
are not affected, referencing the Setting access and the two test methods to
locate where to save and reset the setting.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/helpers/katello/content_options_helper.rb`:
- Around line 95-101: The method filter_cvenvs_by_content_source currently
returns the full cvenvs when available_env_ids is empty, which repopulates
CVEnvs the content source can't serve; change it so that when content_source is
not pulp_primary and available_env_ids.empty? it returns an empty array ([])
instead of cvenvs. Update the early-return logic in
filter_cvenvs_by_content_source to use available_env_ids.empty? to return [] and
keep the later behavior that re-adds current_cvenv elsewhere intact.

In `@app/helpers/katello/kickstart_repository_helper.rb`:
- Around line 59-67: The code rebuilds new_host.content_facet but only restores
content_view_environments for the single-CVEnv case, dropping multi-CVEnv
associations and causing kickstart_repos(new_host) to run without CVEnv
restrictions; fix by copying the host's existing content_view_environments onto
the new facet when host.content_facet.present? (i.e., set
new_host.content_facet.content_view_environments =
host.content_facet.content_view_environments) and keep the existing
single_content_view_environment? branch that resolves CVEnv via
::Katello::ContentViewEnvironment.find_by_cv_and_lce! so both single- and
multi-CVEnv hosts preserve their CVEnv restrictions.

In `@test/controllers/api/v2/content_views_controller_test.rb`:
- Around line 655-659: Replace the order-dependent lookup that uses
alternate_cv.versions.first.id with the CV+LCE lookup helper so alternate_cvenv
is resolved deterministically; specifically, change the find_by call to use the
dedicated helper (e.g.
Katello::ContentViewEnvironment.find_by_content_view_and_lifecycle_environment(alternate_cv,
alternate_env) or the project's equivalent CV+LCE helper) instead of passing
:content_view_version_id => alternate_cv.versions.first.id and :environment_id
=> alternate_env.id.

---

Outside diff comments:
In `@app/controllers/katello/api/v2/activation_keys_controller.rb`:
- Around line 223-233: The current conditional calls
::Katello::ContentViewEnvironment.fetch_content_view_environments when params
like params[:content_view_environments] or params[:content_view_environment_ids]
are present but blank (e.g. "" or []), causing handle_errors to raise before
handle_blank_cvenv_params can clear associations; update the condition in the
controller so it only calls fetch_content_view_environments when the params are
present and not blank (e.g. use .present? or !.blank? on
params[:content_view_environments] and params[:content_view_environment_ids])
and ensure `@content_view_environments` is only set from
fetch_content_view_environments in that non-blank case so
handle_blank_cvenv_params can run for explicit empty payloads without triggering
handle_errors.

In `@test/controllers/api/v2/hosts_controller_test.rb`:
- Around line 77-122: These tests (test_host_contents_cvenv_labels_param and
test_host_contents_cvenv_ids_param) mutate the global
Setting[:allow_multiple_content_views] and do not restore it; capture the
original value before setting it to true and restore it after the test (use a
teardown/ensure block or wrap the test with save/restore) so subsequent tests
are not affected, referencing the Setting access and the two test methods to
locate where to save and reset the setting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 52faa657-395b-43e7-8b46-23a4d00b9d6c

📥 Commits

Reviewing files that changed from the base of the PR and between a05a66a and e57599e.

📒 Files selected for processing (68)
  • app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js
  • app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
  • app/controllers/katello/api/v2/activation_keys_controller.rb
  • app/controllers/katello/api/v2/content_view_versions_controller.rb
  • app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb
  • app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb
  • app/controllers/katello/concerns/authorization/api/v2/content_views_controller.rb
  • app/helpers/katello/content_options_helper.rb
  • app/helpers/katello/hosts_and_hostgroups_helper.rb
  • app/helpers/katello/kickstart_repository_helper.rb
  • app/lib/actions/katello/activation_key/reassign.rb
  • app/lib/actions/katello/content_view/add_to_environment.rb
  • app/lib/actions/katello/content_view/incremental_updates.rb
  • app/lib/actions/katello/content_view/remove.rb
  • app/lib/actions/katello/content_view/remove_from_environment.rb
  • app/lib/actions/katello/environment/destroy.rb
  • app/lib/actions/katello/host/reassign.rb
  • app/lib/actions/katello/host/update_content_view.rb
  • app/lib/actions/katello/organization/destroy.rb
  • app/lib/actions/katello/organization/environment_contents_refresh.rb
  • app/lib/katello/util/cve_hgcf_migrator.rb
  • app/lib/katello/util/cveak_migrator.rb
  • app/lib/katello/util/cvecf_migrator.rb
  • app/lib/katello/validators/generated_content_view_validator.rb
  • app/lib/katello/validators/hostgroup_kickstart_repository_validator.rb
  • app/models/katello/activation_key.rb
  • app/models/katello/authorization/repository.rb
  • app/models/katello/concerns/content_facet_host_extensions.rb
  • app/models/katello/concerns/hostgroup_extensions.rb
  • app/models/katello/concerns/subscription_facet_host_extensions.rb
  • app/models/katello/content_view_environment.rb
  • app/models/katello/content_view_environment_activation_key.rb
  • app/models/katello/content_view_environment_content_facet.rb
  • app/models/katello/host/content_facet.rb
  • app/models/katello/host/info_provider.rb
  • app/models/katello/host/subscription_facet.rb
  • app/models/katello/repository.rb
  • app/services/katello/content_view_manager.rb
  • app/services/katello/product_content_finder.rb
  • app/services/katello/registration_manager.rb
  • app/views/overrides/activation_keys/_host_environment_select.html.erb
  • developer_docs/quick_reference.md
  • test/actions/katello/content_view_test.rb
  • test/actions/katello/environment_test.rb
  • test/controllers/api/v2/activation_keys_controller_test.rb
  • test/controllers/api/v2/api_controller_test.rb
  • test/controllers/api/v2/content_views_controller_test.rb
  • test/controllers/api/v2/hostgroups_controller_test.rb
  • test/controllers/api/v2/hosts_controller_test.rb
  • test/controllers/foreman/hostgroups_controller_test.rb
  • test/factories/host_factory.rb
  • test/helpers/hosts_and_hostgroups_helper_test.rb
  • test/helpers/url_helpers_test.rb
  • test/lib/concerns/renderer_extensions_test.rb
  • test/lib/validators/hostgroup_kickstart_repository_validator_test.rb
  • test/mailers/errata_mailer_test.rb
  • test/models/activation_key_test.rb
  • test/models/authorization/activation_key_authorization_test.rb
  • test/models/concerns/content_facet_host_extensions_test.rb
  • test/models/concerns/host_managed_extensions_test.rb
  • test/models/concerns/hostgroup_extensions_test.rb
  • test/models/content_view_test.rb
  • test/models/erratum_test.rb
  • test/models/host/content_facet_test.rb
  • test/models/hostgroup/content_facet_test.rb
  • test/models/repository_test.rb
  • test/services/katello/registration_manager_test.rb
  • test/support/host_support.rb
✅ Files skipped from review due to trivial changes (10)
  • app/lib/katello/validators/generated_content_view_validator.rb
  • app/lib/actions/katello/content_view/incremental_updates.rb
  • app/models/katello/authorization/repository.rb
  • app/lib/katello/util/cveak_migrator.rb
  • app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
  • app/models/katello/repository.rb
  • app/models/katello/host/info_provider.rb
  • app/lib/katello/util/cvecf_migrator.rb
  • app/services/katello/content_view_manager.rb
  • app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb

Comment thread app/helpers/katello/content_options_helper.rb
Comment thread app/helpers/katello/kickstart_repository_helper.rb
Comment thread test/controllers/api/v2/content_views_controller_test.rb Outdated
@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch from e57599e to 7e76485 Compare May 20, 2026 17:26
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/controllers/katello/api/v2/activation_keys_controller.rb (1)

223-234: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Blank CVEnv params should be normalized before lookup/error handling.

Line 223 can run the lookup path for blank values, and Line 228 may trigger handle_errors before the blank-clearing branch (Lines 246-255). That risks rejecting valid “clear content view environments” updates.

Suggested fix
 def find_content_view_environments
   `@content_view_environments` = []
+  handle_blank_cvenv_params
-  if params_likely_not_from_angularjs? && (params[:content_view_environments] || params[:content_view_environment_ids])
+  if params_likely_not_from_angularjs? &&
+     ((params.key?(:content_view_environments) && params[:content_view_environments].present?) ||
+      (params.key?(:content_view_environment_ids) && params[:content_view_environment_ids].present?))
     `@content_view_environments` = ::Katello::ContentViewEnvironment.fetch_content_view_environments(
       labels: params[:content_view_environments],
       ids: params[:content_view_environment_ids],
       organization: `@organization` || `@activation_key`&.organization)
     if `@content_view_environments.blank`?
       handle_errors(labels: params[:content_view_environments],
       ids: params[:content_view_environment_ids])
     end
   end
-  handle_blank_cvenv_params
   `@organization` ||= `@content_view_environments.first`&.organization
 end

Also applies to: 246-255

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/controllers/katello/api/v2/activation_keys_controller.rb` around lines
223 - 234, The lookup/error path runs before blank CVEnv params are normalized,
causing valid "clear content view environments" updates to be rejected; move or
invoke handle_blank_cvenv_params (or otherwise normalize/strip blank entries
from params[:content_view_environments] and
params[:content_view_environment_ids]) before the conditional that calls
params_likely_not_from_angularjs? and
::Katello::ContentViewEnvironment.fetch_content_view_environments so that
`@content_view_environments` lookup and handle_errors operate on cleaned params;
ensure `@organization` assignment using `@content_view_environments.first` remains
correct after normalization.
♻️ Duplicate comments (1)
app/models/katello/host/content_facet.rb (1)

89-93: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve requested CVEnv ID order and fail fast on unknown IDs.

Line 92 uses ContentViewEnvironment.where(id: cvenv_ids), which silently drops missing IDs and can reorder assignments. That can initialize hosts with an unexpected CVEnv set/priority.

Proposed fix
       if cvenv_ids.present?
-          self.content_view_environments = ContentViewEnvironment.where(id: cvenv_ids)
+          ordered_ids = Array(cvenv_ids).map(&:to_s)
+          cvenvs_by_id = ContentViewEnvironment.where(id: ordered_ids).index_by { |cvenv| cvenv.id.to_s }
+          missing_ids = ordered_ids - cvenvs_by_id.keys
+          raise ActiveRecord::RecordNotFound, "Couldn't find Katello::ContentViewEnvironment IDs: #{missing_ids.join(', ')}" if missing_ids.any?
+
+          self.content_view_environments = ordered_ids.map { |id| cvenvs_by_id.fetch(id) }
       end
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/models/katello/host/content_facet.rb` around lines 89 - 93, The current
assignment uses ContentViewEnvironment.where(id: cvenv_ids) which can drop
unknown IDs and not preserve the requested order; replace this with a lookup
that preserves the input order and raises on missing IDs (e.g. use
ContentViewEnvironment.find(cvenv_ids) or equivalent) and assign the result to
self.content_view_environments; keep the existing presence check for cvenv_ids
(the symbols to edit are cvenv_ids, content_view_environments, and
ContentViewEnvironment.where).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@app/controllers/katello/api/v2/activation_keys_controller.rb`:
- Around line 223-234: The lookup/error path runs before blank CVEnv params are
normalized, causing valid "clear content view environments" updates to be
rejected; move or invoke handle_blank_cvenv_params (or otherwise normalize/strip
blank entries from params[:content_view_environments] and
params[:content_view_environment_ids]) before the conditional that calls
params_likely_not_from_angularjs? and
::Katello::ContentViewEnvironment.fetch_content_view_environments so that
`@content_view_environments` lookup and handle_errors operate on cleaned params;
ensure `@organization` assignment using `@content_view_environments.first` remains
correct after normalization.

---

Duplicate comments:
In `@app/models/katello/host/content_facet.rb`:
- Around line 89-93: The current assignment uses
ContentViewEnvironment.where(id: cvenv_ids) which can drop unknown IDs and not
preserve the requested order; replace this with a lookup that preserves the
input order and raises on missing IDs (e.g. use
ContentViewEnvironment.find(cvenv_ids) or equivalent) and assign the result to
self.content_view_environments; keep the existing presence check for cvenv_ids
(the symbols to edit are cvenv_ids, content_view_environments, and
ContentViewEnvironment.where).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bcdc3b34-d900-4b59-9cbe-5a7da34de077

📥 Commits

Reviewing files that changed from the base of the PR and between e57599e and 7e76485.

📒 Files selected for processing (68)
  • app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js
  • app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
  • app/controllers/katello/api/v2/activation_keys_controller.rb
  • app/controllers/katello/api/v2/content_view_versions_controller.rb
  • app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb
  • app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb
  • app/controllers/katello/concerns/authorization/api/v2/content_views_controller.rb
  • app/helpers/katello/content_options_helper.rb
  • app/helpers/katello/hosts_and_hostgroups_helper.rb
  • app/helpers/katello/kickstart_repository_helper.rb
  • app/lib/actions/katello/activation_key/reassign.rb
  • app/lib/actions/katello/content_view/add_to_environment.rb
  • app/lib/actions/katello/content_view/incremental_updates.rb
  • app/lib/actions/katello/content_view/remove.rb
  • app/lib/actions/katello/content_view/remove_from_environment.rb
  • app/lib/actions/katello/environment/destroy.rb
  • app/lib/actions/katello/host/reassign.rb
  • app/lib/actions/katello/host/update_content_view.rb
  • app/lib/actions/katello/organization/destroy.rb
  • app/lib/actions/katello/organization/environment_contents_refresh.rb
  • app/lib/katello/util/cve_hgcf_migrator.rb
  • app/lib/katello/util/cveak_migrator.rb
  • app/lib/katello/util/cvecf_migrator.rb
  • app/lib/katello/validators/generated_content_view_validator.rb
  • app/lib/katello/validators/hostgroup_kickstart_repository_validator.rb
  • app/models/katello/activation_key.rb
  • app/models/katello/authorization/repository.rb
  • app/models/katello/concerns/content_facet_host_extensions.rb
  • app/models/katello/concerns/hostgroup_extensions.rb
  • app/models/katello/concerns/subscription_facet_host_extensions.rb
  • app/models/katello/content_view_environment.rb
  • app/models/katello/content_view_environment_activation_key.rb
  • app/models/katello/content_view_environment_content_facet.rb
  • app/models/katello/host/content_facet.rb
  • app/models/katello/host/info_provider.rb
  • app/models/katello/host/subscription_facet.rb
  • app/models/katello/repository.rb
  • app/services/katello/content_view_manager.rb
  • app/services/katello/product_content_finder.rb
  • app/services/katello/registration_manager.rb
  • app/views/overrides/activation_keys/_host_environment_select.html.erb
  • developer_docs/quick_reference.md
  • test/actions/katello/content_view_test.rb
  • test/actions/katello/environment_test.rb
  • test/controllers/api/v2/activation_keys_controller_test.rb
  • test/controllers/api/v2/api_controller_test.rb
  • test/controllers/api/v2/content_views_controller_test.rb
  • test/controllers/api/v2/hostgroups_controller_test.rb
  • test/controllers/api/v2/hosts_controller_test.rb
  • test/controllers/foreman/hostgroups_controller_test.rb
  • test/factories/host_factory.rb
  • test/helpers/hosts_and_hostgroups_helper_test.rb
  • test/helpers/url_helpers_test.rb
  • test/lib/concerns/renderer_extensions_test.rb
  • test/lib/validators/hostgroup_kickstart_repository_validator_test.rb
  • test/mailers/errata_mailer_test.rb
  • test/models/activation_key_test.rb
  • test/models/authorization/activation_key_authorization_test.rb
  • test/models/concerns/content_facet_host_extensions_test.rb
  • test/models/concerns/host_managed_extensions_test.rb
  • test/models/concerns/hostgroup_extensions_test.rb
  • test/models/content_view_test.rb
  • test/models/erratum_test.rb
  • test/models/host/content_facet_test.rb
  • test/models/hostgroup/content_facet_test.rb
  • test/models/repository_test.rb
  • test/services/katello/registration_manager_test.rb
  • test/support/host_support.rb
✅ Files skipped from review due to trivial changes (13)
  • app/controllers/katello/concerns/authorization/api/v2/content_views_controller.rb
  • app/lib/actions/katello/content_view/add_to_environment.rb
  • app/controllers/katello/api/v2/content_view_versions_controller.rb
  • app/lib/actions/katello/content_view/remove_from_environment.rb
  • test/models/repository_test.rb
  • app/lib/actions/katello/content_view/incremental_updates.rb
  • app/lib/actions/katello/environment/destroy.rb
  • app/models/katello/repository.rb
  • app/lib/katello/validators/generated_content_view_validator.rb
  • app/services/katello/content_view_manager.rb
  • app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb
  • app/lib/katello/util/cvecf_migrator.rb
  • app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb

@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch from 7e76485 to f017428 Compare May 20, 2026 17:40
@jeremylenz
Copy link
Copy Markdown
Member Author

ok, I think rabbit is happy (for now...)

@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch 2 times, most recently from d8a10c5 to dc16926 Compare May 21, 2026 15:21
@jeremylenz
Copy link
Copy Markdown
Member Author

@lfu @nofaralfasi Inheritance should be working better now on the create host form.

Hey, "John" 😄

Addressed all three comments:

  1. Lucy (JS): Default CVEnv now shows just the environment name (e.g. "Library") instead of "Library / Default Organization View", matching the Ruby helper behavior
  2. Lucy (helper): Added h() escaping to org.name on line 24, matching the fix we already made on line 77
  3. John (content_facet.rb): Added inherited_content_view_environment_id as a public method on hostgroup_extensions, replacing the send(:inherited_ancestry_attribute, ...) call

@nofaralfasi
Copy link
Copy Markdown
Contributor

Is it intentional that the Content View Environment field is not available on the host edit form?
Screenshot From 2026-05-27 17-07-56

@jeremylenz
Copy link
Copy Markdown
Member Author

@nofaralfasi Yes, that was an intentional decision from a few years ago due to the complexities of content source / CVenv coherence and now also MultiCV. You can use the "Change content source" link to change the existing host's CVEnvs.

Copy link
Copy Markdown
Member

@jturel jturel left a comment

Choose a reason for hiding this comment

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

Not seeing any issues in my testing - let's ship it (pending ack from other reviewers)

@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch from 8d51409 to 6c72df3 Compare May 27, 2026 20:32
@jeremylenz
Copy link
Copy Markdown
Member Author

@lfu Added display_name on ContentViewEnvironment and replaced both inline formatting sites in the helper. (I kept host_and_hostgroup_edit as-is since that's a legacy JS file.)

@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch from 6c72df3 to f0a78a4 Compare May 27, 2026 20:52
@jeremylenz
Copy link
Copy Markdown
Member Author

@lfu actually, changed it so it just uses label. Much simpler and correct everywhere this way.

@nofaralfasi
Copy link
Copy Markdown
Contributor

nofaralfasi commented May 28, 2026

@nofaralfasi Yes, that was an intentional decision from a few years ago due to the complexities of content source / CVenv coherence and now also MultiCV. You can use the "Change content source" link to change the existing host's CVEnvs.

Thanks, I tried that flow, but on my side the Change content source page does not show the host’s currently assigned CVEnvs.
It opens with an empty/default selection (as if no CVEnv is set), so I can’t verify preservation from that screen:
Screenshot From 2026-05-28 15-51-42

Comment thread app/models/katello/content_view_environment.rb Outdated
@jeremylenz
Copy link
Copy Markdown
Member Author

jeremylenz commented May 28, 2026

@nofaralfasi We do have a special case (via url params) for arriving at Change Content Source from host edit. It shows this banner when the selected content source is the same as the existing:

image

Also, the buttons change from "Run job invocation / Update hosts manually" to simply "Save," because there's no client-side step necessary if content source didn't actually change.

However, it's true that you do still start with a blank form.

Other than that, the way to confirm a host's current CVEnvs is just to view host details. I have confirmed that none of this is a change from previous behavior.

@jeremylenz jeremylenz force-pushed the sat-38100-remove-deprecated-cv-lce-params branch from f0a78a4 to 9b3d6c4 Compare May 28, 2026 13:48
@jeremylenz
Copy link
Copy Markdown
Member Author

@lfu updated 👍

Update content_facet_ignore_update? to check content_view_environment_ids
instead of the removed content_view_id/lifecycle_environment_id params.
Without this, Host.new with content_facet_attributes would silently reject
the nested attributes and not build the content facet.

Update all test files to use content_view_environment_ids (hosts) and
content_view_environment_id (hostgroups) instead of the removed params.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nofaralfasi
Copy link
Copy Markdown
Contributor

@jeremylenz I’m still seeing “Run job invocation / Update hosts manually” in this flow, not the single “Save” button shown in your screenshot:
image

@jeremylenz
Copy link
Copy Markdown
Member Author

  1. You have to arrive there via the Change Content Source link on the host edit page
  2. The selected content source must be the same as the existing

@jeremylenz
Copy link
Copy Markdown
Member Author

Notice that the link includes url params
/change_host_content_source?fromPage=hostEdit&host_id=2&initialContentSourceId=1

@nofaralfasi
Copy link
Copy Markdown
Contributor

Notice that the link includes url params /change_host_content_source?fromPage=hostEdit&host_id=2&initialContentSourceId=1

I’m reaching that page via the Change content source link on the host edit page, and the selected content source is the same as the current one.
I still see “Run job invocation / Update hosts manually” instead of “Save.”

This is the exact URL I get:
https://ip-10-0-168-50.rhos-01.prod.psi.rdu2.redhat.com/change_host_content_source?fromPage=hostEdit&host_id=17&initialContentSourceId=

Do you know why initialContentSourceId is empty here?

@jeremylenz
Copy link
Copy Markdown
Member Author

It would be empty if your host somehow has a nil content source. Check in console, or in host details Details tab > Registration details card.

@jeremylenz
Copy link
Copy Markdown
Member Author

This would be the case if you're using the Foreman base host, or an unregistered host.

@nofaralfasi
Copy link
Copy Markdown
Contributor

Thanks @jeremylenz!
I checked this with Codex earlier, and it initially suggested this was unrelated to the host being unregistered.
After retesting, I can confirm the behavior is as you described: on an unregistered/base host I see the job/manual buttons, and with a registered host it works properly (shows the expected Save flow).

Copy link
Copy Markdown
Contributor

@nofaralfasi nofaralfasi left a comment

Choose a reason for hiding this comment

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

I tested all scenarios from the PR test plan, and they all pass on my side:

  • Host create with hostgroup CVEnv inheritance/pre-population: passed
  • Edit existing host (CVEnv preserved): passed
  • Edit multi-CVEnv host (all CVEnvs preserved): passed
  • Create/edit hostgroup with CVEnv: passed
  • AK create via API with content_view_environment_ids: passed
  • AK update via API with content_view_environment_ids: passed
  • Removed legacy params (content_view_id, lifecycle_environment_id) are no longer accepted/effective on host/AK/hostgroup APIs: passed

Copy link
Copy Markdown
Member

@lfu lfu left a comment

Choose a reason for hiding this comment

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

LGTM code wise.

@jeremylenz
Copy link
Copy Markdown
Member Author

Thanks all for the reviews!

@jeremylenz jeremylenz merged commit a46d7af into Katello:master May 28, 2026
22 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants