Skip to content

Commit

Permalink
[CP] Katello 4.12.0.rc2 cherry picks (#10916)
Browse files Browse the repository at this point in the history
* Release 4.12.0-rc1 (#10909)

* Fixes #37137 - Use insert_all when creating available module streams (#10878)

* Fixes #37137 - Use insert_all when creating available module streams

(cherry picked from commit 7458f70)

* Fixes #37178 - use safe navigation for operatingsystem (#10897)

(cherry picked from commit 664488d)

* Refs #37202 - display name according to setting in host collection

(cherry picked from commit de39a36)

* Fixes #37192 - Use with_enabled_email scope (#10901)

* Fixes #37192 - Use with_enabled_email scope

Instead of typing out the same query explicitly.

* Refs #37192 - Bump required foreman version

(cherry picked from commit 1ace8e5)

* Refs #37203 - display name according to setting in errata host list

(cherry picked from commit 2775554)

* Fixes #37214 - Change 'default' for limit to environment checkbox in activation-key and content-host

(cherry picked from commit 9d0a338)

* Fixes #37108 - Preload content_view_components (#10864)

(cherry picked from commit d98c17b)

* Fixes #36976 - Too many audit records slow down CV loading (#10911)

(cherry picked from commit 30c6977)

* Refs #37201 - display short host name in activation keys menu

(cherry picked from commit 8164043)

* Fixes #37187 - Update ACS refresh Pulp fixtures + fix repository_test test

(cherry picked from commit 99c7857)

* Fixes #37198 - Allow installedDeb package attributes in safemode

(cherry picked from commit b5d785f)

* Fixes #37197 - Kickstart repository correctly listed on hostgroup

(cherry picked from commit 35c49b1)

* Fixes #37169 - Managing a Hosts Repository Sets does not behave as expected (#10905)

(cherry picked from commit 6420cf8)

---------

Co-authored-by: Jeremy Lenz <[email protected]>
Co-authored-by: Matěj Mudra <[email protected]>
Co-authored-by: Adam Růžička <[email protected]>
Co-authored-by: Manisha Singhal <[email protected]>
Co-authored-by: Bernhard Suttner <[email protected]>
Co-authored-by: Samir Jha <[email protected]>
Co-authored-by: ianballou <[email protected]>
Co-authored-by: Bernhard Suttner <[email protected]>
Co-authored-by: Partha Aji <[email protected]>
Co-authored-by: Thorben <[email protected]>
  • Loading branch information
11 people authored Mar 7, 2024
1 parent ab7f2d6 commit 1bd79a2
Show file tree
Hide file tree
Showing 34 changed files with 3,116 additions and 2,424 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<<<<<<< HEAD
# 4.12.0.rc1 Mile 42 (2024-02-27)
=======
# 4.12.0-rc1 Mile 42 (2024-02-27)
>>>>>>> df8164b7fa (Release 4.12.0-rc1 (#10909))
## Features

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/katello/api/v2/content_views_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def filtered_associations
param_group :search, Api::V2::ApiController
add_scoped_search_description_for(ContentView)
def index
content_view_includes = [:activation_keys, :content_view_versions,
content_view_includes = [:activation_keys, :content_view_versions, :content_view_components,
:environments, :organization, :repositories]
respond(:collection => scoped_search(index_relation.distinct, :name, :asc, :includes => content_view_includes))
end
Expand Down
13 changes: 13 additions & 0 deletions app/controllers/katello/api/v2/host_subscriptions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ def product_content
param :content_overrides_search, Hash, :desc => N_("Content override search parameters") do
param_group :search, Api::V2::ApiController
param :enabled, :bool, :desc => N_("Set true to override to enabled; Set false to override to disabled.'"), :required => false
param :limit_to_env, :bool, :desc => N_("Limit actions to content in the host's environment."), :required => false
param :remove, :bool, :desc => N_("Set true to remove an override and reset it to 'default'"), :required => false
end
def content_override
Expand Down Expand Up @@ -232,10 +233,22 @@ def action_permission

def find_content_overrides
if !params.dig(:content_overrides_search, :search).nil?

content_labels = ::Katello::Content.joins(:product_contents)
.where("#{Katello::ProductContent.table_name}.product_id": @host.organization.products.subscribable.enabled)
.search_for(params[:content_overrides_search][:search])
.pluck(:label)

if Foreman::Cast.to_bool(params.dig(:content_overrides_search, :limit_to_env))
env_content = ProductContentFinder.new(
:match_subscription => false,
:match_environment => true,
:consumable => @host.subscription_facet
).product_content
env_content_labels = ::Katello::Content.find(env_content.pluck(:content_id)).pluck(:label)
content_labels &= env_content_labels
end

@content_overrides = content_labels.map do |label|
{ content_label: label,
value: Foreman::Cast.to_bool(params[:content_overrides_search][:enabled]),
Expand Down
2 changes: 1 addition & 1 deletion app/lib/actions/katello/capsule_content/sync.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def notify_on_failure(_plan)
notification = MailNotification[:proxy_sync_failure]
proxy = SmartProxy.find(input.fetch(:smart_proxy, {})[:id])
subjects = subjects(input[:options]).merge(smart_proxy: proxy)
notification.users.where(disabled: [nil, false], mail_enabled: true).each do |user|
notification.users.with_enabled_email.each do |user|
notification.deliver(subjects.merge(user: user, task: task))
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/lib/actions/katello/content_view/promote.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def plan(version, environments, is_force = false, description = nil, incremental
def notify_on_failure(_plan)
notification = MailNotification[:content_view_promote_failure]
view = ::Katello::ContentView.find(input.fetch(:content_view, {})[:id])
notification.users.where(disabled: [nil, false], mail_enabled: true).each do |user|
notification.users.with_enabled_email.each do |user|
notification.deliver(user: user, content_view: view, task: task)
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/lib/actions/katello/content_view/publish.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def trigger_capsule_sync(_execution_plan)
def notify_on_failure(_plan)
notification = MailNotification[:content_view_publish_failure]
view = ::Katello::ContentView.find(input.fetch(:content_view, {})[:id])
notification.users.where(disabled: [nil, false], mail_enabled: true).each do |user|
notification.users.with_enabled_email.each do |user|
notification.deliver(user: user, content_view: view, task: task)
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/lib/actions/katello/repository/sync.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def rescue_strategy
def notify_on_failure(_plan)
notification = MailNotification[:repository_sync_failure]
repo = ::Katello::Repository.find(input.fetch(:repository, {})[:id])
notification.users.where(disabled: [nil, false], mail_enabled: true).each do |user|
notification.users.with_enabled_email.each do |user|
notification.deliver(user: user, repo: repo, task: task)
end
end
Expand Down
63 changes: 45 additions & 18 deletions app/models/katello/concerns/host_managed_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -325,40 +325,67 @@ def import_enabled_repositories(repos)
content_facet.update_repositories_by_paths(paths.compact)
end

def import_module_streams(module_streams)
streams = {}
module_streams.each do |module_stream|
stream = AvailableModuleStream.create_or_find_by!(name: module_stream["name"],
context: module_stream["context"],
stream: module_stream["stream"])
streams[stream.id] = module_stream
def available_module_stream_id_from(name:, stream:, context:)
@indexed_available_module_streams ||= Katello::AvailableModuleStream.all.index_by do |available_module_stream|
"#{available_module_stream.name}-#{available_module_stream.stream}-#{available_module_stream.context}"
end
sync_available_module_stream_associations(streams)
@indexed_available_module_streams["#{name}-#{stream}-#{context}"]&.id
end

def import_module_streams(module_streams)
# module_streams looks like this
# {"name"=>"389-ds", "stream"=>"1.4", "version"=>"8030020201203210520", "context"=>"e114a9e7", "arch"=>"x86_64", "profiles"=>[], "installed_profiles"=>[], "status"=>"default", "active"=>false}
streams = module_streams.map do |module_stream|
{
name: module_stream["name"],
stream: module_stream["stream"],
context: module_stream["context"]
}
end
if streams.any?
AvailableModuleStream.insert_all(
streams,
unique_by: %w[name stream context],
returning: %w[id name stream context]
)
end
indexed_module_streams = module_streams.index_by do |module_stream|
available_module_stream_id_from(
name: module_stream["name"],
stream: module_stream["stream"],
context: module_stream["context"]
)
end
sync_available_module_stream_associations(indexed_module_streams)
end

def sync_available_module_stream_associations(new_available_module_streams)
upgradable_streams = self.host_available_module_streams.where(:available_module_stream_id => new_available_module_streams.keys)
new_associated_ids = new_available_module_streams.keys.compact
upgradable_streams = self.host_available_module_streams.where(:available_module_stream_id => new_associated_ids)
old_associated_ids = self.available_module_stream_ids
delete_ids = old_associated_ids - new_available_module_streams.keys
delete_ids = old_associated_ids - new_associated_ids

if delete_ids.any?
self.host_available_module_streams.where(:available_module_stream_id => delete_ids).delete_all
end

new_ids = new_available_module_streams.keys - old_associated_ids
new_ids.each do |new_id|
new_ids = new_associated_ids - old_associated_ids

hams_to_create = new_ids.map do |new_id|
module_stream = new_available_module_streams[new_id]
status = module_stream["status"]
# Set status to "unknown" only if the active field is in use and set to false and the module is enabled
if enabled_module_stream_inactive?(module_stream)
status = "unknown"
end
self.host_available_module_streams.create!(host_id: self.id,
available_module_stream_id: new_id,
installed_profiles: module_stream["installed_profiles"],
status: status)
end

{
host_id: self.id,
available_module_stream_id: new_id,
installed_profiles: module_stream["installed_profiles"],
status: status
}
end
HostAvailableModuleStream.insert_all(hams_to_create) if hams_to_create.any?
upgradable_streams.each do |hams|
module_stream = new_available_module_streams[hams.available_module_stream_id]
shared_keys = hams.attributes.keys & module_stream.keys
Expand Down
5 changes: 5 additions & 0 deletions app/models/katello/concerns/hostgroup_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ def lifecycle_environment
Katello::KTEnvironment.find_by(:id => inherited_lifecycle_environment_id)
end

def kickstart_repository
return super if ancestry.nil? || self.kickstart_repository_id.present?
Katello::Repository.find_by(:id => inherited_kickstart_repository_id)
end

# instead of calling nested_attribute_for(:content_source_id) in Foreman, define the methods explictedly
def content_source
return super if ancestry.nil? || self.content_source_id.present?
Expand Down
64 changes: 23 additions & 41 deletions app/models/katello/content_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -770,45 +770,6 @@ def related_composite_cvs
content_views
end

def audited_cv_repositories_since_last_publish
audited_repositories = self.audits.filter do |a|
!a.audited_changes["repository_ids"].nil?
end
if latest_version_object
audited_repositories.filter! { |a| a.created_at > latest_version_object.created_at }
end
audited_repositories
end

def audited_cv_repository_changed
audited_repositories_changes = Audit.where(auditable_id: repositories, auditable_type: "Katello::Repository").filter do |a|
a.audited_changes["publication_href"].present? || a.audited_changes["version_href"].present?
end
if latest_version_object
audited_repositories_changes = audited_repositories_changes.filter { |a| a.created_at > latest_version_object.created_at }
end
audited_repositories_changes
end

def audited_cv_filters_changed
audited_filters = Audit.where(auditable_type: "Katello::ContentViewFilter",
associated_id: id,
associated_type: "Katello::ContentView")
if latest_version_object
audited_filters = audited_filters.filter { |a| a.created_at > latest_version_object.created_at }
end
audited_filters
end

def audited_cv_filter_rules_changed
audited_filter_rules = Audit.where(associated_id: id,
associated_type: "Katello::ContentView").where("auditable_type LIKE '%FilterRule%'")
if latest_version_object
audited_filter_rules = audited_filter_rules.filter { |a| a.created_at > latest_version_object.created_at }
end
audited_filter_rules
end

def composite_cv_components_changed?
return true unless latest_version_object
published_component_version_ids = latest_version_object.components.pluck(:id) || []
Expand Down Expand Up @@ -874,8 +835,29 @@ def needs_publish?
end

def audited_changes_present?
audited_cv_repositories_since_last_publish.present? || audited_cv_repository_changed.present? ||
audited_cv_filters_changed.present? || audited_cv_filter_rules_changed.present?
latest_version_created_at = latest_version_object.created_at
cv_repository_ids = repositories.pluck(:id)

audited_changes_like = ->(param) {
Arel.sql("#{Audit.table_name}.audited_changes ilike '%#{param}%'")
}

table = Audit.arel_table
repository_condition = table[:auditable_id].eq(id).and(audited_changes_like.call("repository_ids"))

cv_repository_condition = table[:auditable_id].in(cv_repository_ids)
.and(table[:auditable_type].eq('Katello::Repository'))
.and(Arel.sql("(#{audited_changes_like.call("publication_href")} OR #{audited_changes_like.call("version_href")})"))

content_view_filter_condition = table[:auditable_type].eq('Katello::ContentViewFilter').and(table[:associated_id].eq(id))

filter_rule_condition = table[:associated_id].eq(id).and(table[:auditable_type].matches('%FilterRule%'))

base_query = table[:created_at].gt(latest_version_created_at)

final_query = base_query.and(repository_condition.or(cv_repository_condition).or(content_view_filter_condition).or(filter_rule_condition))

Audit.where(final_query).exists?
end

def dependency_solving_changed?
Expand Down
12 changes: 12 additions & 0 deletions app/models/katello/installed_deb.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
module Katello
class InstalledDeb < Katello::Model
apipie :class, desc: "A class representing #{model_name.human} object" do
name 'Installed Deb'
refs 'InstalledDeb'
sections only: %w[all additional]
property :name, String, desc: 'Returns name of the package'
property :version, String, desc: 'Returns package version'
property :architecture, String, desc: 'Returns package architecture'
end
class Jail < Safemode::Jail
allow :name, :version, :architecture
end

has_many :host_installed_debs, :class_name => "Katello::HostInstalledDeb", :dependent => :destroy, :inverse_of => :installed_deb
has_many :hosts, :through => :host_installed_debs, :class_name => "::Host"

Expand Down
4 changes: 4 additions & 0 deletions app/models/katello/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ def set_pulp_id
self.pulp_id = SecureRandom.uuid if self.pulp_id.length > PULP_ID_MAX_LENGTH
end

def self.attribute_name
:name
end

def set_container_repository_name
self.container_repository_name = Repository.safe_render_container_name(self)
end
Expand Down
1 change: 0 additions & 1 deletion app/views/katello/api/v2/content_views/base.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ attributes :import_only
attributes :generated_for
attributes :related_cv_count
attributes :related_composite_cvs
attributes :needs_publish? => :needs_publish
attributes :filtered? => :filtered

node :next_version do |content_view|
Expand Down
1 change: 1 addition & 0 deletions app/views/katello/api/v2/content_views/show.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ object @resource
extends "katello/api/v2/content_views/base"

attributes :content_host_count
attributes :needs_publish? => :needs_publish

node :errors do
unless @resource.valid?
Expand Down
4 changes: 2 additions & 2 deletions app/views/katello/api/v2/hosts/base.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ object @resource
attributes :id, :name, :description

node :operatingsystem_family do |resource|
resource.operatingsystem.family
resource.operatingsystem&.family
end

node :operatingsystem_major do |resource|
resource.operatingsystem.major
resource.operatingsystem&.major
end

if @facet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
kickstart_repo_id = kickstart_repository_id(@host, :selected_host_group => @host&.hostgroup)
kickstart_options = kickstart_repository_options(@host, :selected_host_group => @host&.hostgroup)
elsif using_hostgroups_page?
kickstart_repo_id = kickstart_repository_id(@host, :selected_host_group => @host&.hostgroup)
kickstart_repo_id = kickstart_repository_id(@hostgroup, :selected_host_group => @host&.hostgroup)
kickstart_options = kickstart_repository_options(@hostgroup)
else
kickstart_repo_id = kickstart_repository_id(@host, :selected_host_group => @hostgroup)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ angular.module('Bastion.activation-keys').controller('ActivationKeyRepositorySet

$scope.contentAccessModes = {
contentAccessModeAll: $scope.simpleContentAccessEnabled,
contentAccessModeEnv: false
contentAccessModeEnv: true
};

$scope.selectRepositoryType = function () {
Expand All @@ -56,6 +56,8 @@ angular.module('Bastion.activation-keys').controller('ActivationKeyRepositorySet
$scope.nutupane.refresh();
};

$scope.toggleFilters();

success = function () {
$scope.table.working = false;
Notification.setSuccessMessage(translate('Repository Sets settings saved successfully.'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
ng-controller="ContentHostStatusController">
<td bst-table-cell>
<span ng-switch="newHostDetailsUI">
<a ng-switch-when="true" ng-href="/new/hosts/{{host.name}}">{{ host.name }}</a>
<a ng-switch-when="false" ui-sref="content-host.info({hostId: host.id})">{{ host.name }}</a>
<a ng-switch-when="true" ng-href="/new/hosts/{{host.name}}">{{ host.display_name }}</a>
<a ng-switch-when="false" ui-sref="content-host.info({hostId: host.id})">{{ host.display_name }}</a>
</span>
</td>
<td bst-table-cell>{{ host.content_facet_attributes.lifecycle_environment.name }}</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ <h3 translate>Apply to Content Hosts</h3>
ng-controller="ContentHostStatusController">
<td bst-table-cell>
<span ng-switch="newHostDetailsUI">
<a ng-switch-when="true" ng-href="/new/hosts/{{contentHost.name}}/content">{{ contentHost.name }}</a>
<a ng-switch-when="false" ui-sref="content-host.info({hostId: contentHost.id})">{{ contentHost.name }}</a>
<a ng-switch-when="true" ng-href="/new/hosts/{{contentHost.name}}/content">{{ contentHost.display_name }}</a>
<a ng-switch-when="false" ui-sref="content-host.info({hostId: contentHost.id})">{{ contentHost.display_name }}</a>
</span>
</td>
<td bst-table-cell>{{ contentHost.operatingsystem_name }}</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
</td>
<td bst-table-cell >
<span ng-switch="newHostDetailsUI">
<a ng-switch-when="true" ng-href="/new/hosts/{{host.name}}">{{ host.name }}</a>
<a ng-switch-when="false" ui-sref="content-host.info({hostId: host.id})">{{ host.name }}</a>
<a ng-switch-when="true" ng-href="/new/hosts/{{host.name}}">{{ host.display_name }}</a>
<a ng-switch-when="false" ui-sref="content-host.info({hostId: host.id})">{{ host.display_name }}</a>
</span>
</td>
<td bst-table-cell >{{ host.content_facet_attributes.lifecycle_environment.name}}</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
</td>
<td bst-table-cell >
<span ng-switch="newHostDetailsUI">
<a ng-switch-when="true" ng-href="/new/hosts/{{host.name}}">{{ host.name }}</a>
<a ng-switch-when="false" ui-sref="content-host.info({hostId: host.id})">{{ host.name }}</a>
<a ng-switch-when="true" ng-href="/new/hosts/{{host.name}}">{{ host.display_name }}</a>
<a ng-switch-when="false" ui-sref="content-host.info({hostId: host.id})">{{ host.display_name }}</a>
</span>
</td>
<td bst-table-cell >{{ host.content_facet_attributes.lifecycle_environment.name}}</td>
Expand Down
2 changes: 1 addition & 1 deletion lib/katello/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# rubocop:disable Metrics/BlockLength

Foreman::Plugin.register :katello do
requires_foreman '>= 3.7'
requires_foreman '>= 3.11'
register_gettext

sub_menu :top_menu, :content_menu, :caption => N_('Content'),
Expand Down
Loading

0 comments on commit 1bd79a2

Please sign in to comment.