From a6fe79d7edc7019da20435219d29fae112fa9e95 Mon Sep 17 00:00:00 2001 From: Markus Bucher Date: Mon, 20 Sep 2021 18:04:42 +0200 Subject: [PATCH] Fixes #33525 - Add debs packages_restrict_latest --- app/controllers/katello/api/v2/debs_controller.rb | 11 +++++++++++ app/models/katello/deb.rb | 5 ++++- test/controllers/api/v2/debs_controller_test.rb | 10 ++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/controllers/katello/api/v2/debs_controller.rb b/app/controllers/katello/api/v2/debs_controller.rb index 39ef90152ce..36b2b095e92 100644 --- a/app/controllers/katello/api/v2/debs_controller.rb +++ b/app/controllers/katello/api/v2/debs_controller.rb @@ -39,6 +39,7 @@ def auto_complete_arch param :host_id, :number, :desc => N_("Host id to list applicable deb packages for") param :packages_restrict_applicable, :boolean, :desc => N_("Return deb packages that are applicable to one or more hosts (defaults to true if host_id is specified)") param :packages_restrict_upgradable, :boolean, :desc => N_("Return deb packages that are upgradable on one or more hosts") + param :packages_restrict_latest, :boolean, :desc => N_("Return only the latest version of each package") param :available_for, String, :desc => N_("Return deb packages that can be added to the specified object. Only the value 'content_view_version' is supported.") param_group :search, ::Katello::Api::V2::ApiController def index @@ -66,6 +67,16 @@ def custom_index_relation(collection) collection end + def final_custom_index_relation(collection) + # :packages_restrict_latest is intended to filter the result set after all + # other constraints have been applied, including the scoped_search + # constraints. If any constraints are applied after this, then a package + # will not be returned if its latest version does not match those + # constraints, even if an older version does match those constraints. + collection = Katello::Deb.latest(collection) if ::Foreman::Cast.to_bool(params[:packages_restrict_latest]) + collection + end + private def find_hosts diff --git a/app/models/katello/deb.rb b/app/models/katello/deb.rb index 0384ff3184c..a6ce02294b9 100644 --- a/app/models/katello/deb.rb +++ b/app/models/katello/deb.rb @@ -96,7 +96,10 @@ def self.applicable_to_hosts(hosts) end def self.latest(_relation) - fail 'NotImplemented' + return relation.joins( + "LEFT JOIN (#{relation.to_sql}) AS katello_debs2 ON " \ + 'katello_debs.name=katello_debs2.name AND deb_version_cmp(katello_debs.version,katello_debs2.version) < 0' + ).where('katello_debs2.version IS NULL') end end end diff --git a/test/controllers/api/v2/debs_controller_test.rb b/test/controllers/api/v2/debs_controller_test.rb index ea3c7daf12c..c5d1ebf59a9 100644 --- a/test/controllers/api/v2/debs_controller_test.rb +++ b/test/controllers/api/v2/debs_controller_test.rb @@ -7,6 +7,7 @@ def models @version = ContentViewVersion.first @deb = katello_debs(:one) @host = hosts(:one) + @org = get_organization end def setup @@ -70,6 +71,15 @@ def test_index_with_available_for_content_view_version assert_includes ids, @deb.id end + def test_index_with_latest + response = get :index, params: { :packages_restrict_latest => true, :organization_id => @org.id } + + assert_response :success + ids = JSON.parse(response.body)['results'].map { |p| p['id'] } + assert_includes ids, katello_debs(:one_new).id + refute_includes ids, @deb.id + end + def test_index_protected assert_protected_action(:index, @auth_permissions, @unauth_permissions) do get :index, params: { :repository_id => @repo.id }