diff --git a/app/models/foreman_puppet/config_group.rb b/app/models/foreman_puppet/config_group.rb index ef3d8949..5b6869ce 100644 --- a/app/models/foreman_puppet/config_group.rb +++ b/app/models/foreman_puppet/config_group.rb @@ -16,7 +16,9 @@ class ConfigGroup < ApplicationRecord validates :name, presence: true, uniqueness: true - scope :assigned_to_hosts, -> { where(id: ForemanPuppet::HostConfigGroup.select(:config_group_id)) } + scope :assigned_to_hosts, lambda { + where(id: ForemanPuppet::HostConfigGroup.assigned_to_taxonomy.select(:config_group_id)) + } scoped_search on: :name, complete_value: true scoped_search relation: :puppetclasses, on: :name, complete_value: true, rename: :puppetclass, only_explicit: true, operators: ['= ', '~ '] diff --git a/app/models/foreman_puppet/host_config_group.rb b/app/models/foreman_puppet/host_config_group.rb index 80102ddd..8b9f10e1 100644 --- a/app/models/foreman_puppet/host_config_group.rb +++ b/app/models/foreman_puppet/host_config_group.rb @@ -8,6 +8,18 @@ class HostConfigGroup < ApplicationRecord validates :host_id, uniqueness: { scope: %i[config_group_id host_type] } + scope :assigned_to_taxonomy, lambda { + host_facets = ForemanPuppet::HostPuppetFacet + .where(host_id: ::Host::Managed.reorder(nil).select(:id)) + .select(:id) + hostgroup_facets = ForemanPuppet::HostgroupPuppetFacet + .where(hostgroup_id: ::Hostgroup.unscoped.with_taxonomy_scope.reorder(nil).select(:id)) + .select(:id) + + where(host_type: ForemanPuppet::HostPuppetFacet.polymorphic_name, host_id: host_facets) + .or(where(host_type: ForemanPuppet::HostgroupPuppetFacet.polymorphic_name, host_id: hostgroup_facets)) + } + def check_permissions_after_save true end diff --git a/app/models/foreman_puppet/puppetclass.rb b/app/models/foreman_puppet/puppetclass.rb index ca8e3db3..403d994d 100644 --- a/app/models/foreman_puppet/puppetclass.rb +++ b/app/models/foreman_puppet/puppetclass.rb @@ -42,10 +42,21 @@ class Puppetclass < ApplicationRecord default_scope -> { order(:name) } scope :assigned_to_hosts, lambda { - direct = ForemanPuppet::HostClass.select(:puppetclass_id) - via_hostgroup = ForemanPuppet::HostgroupClass.select(:puppetclass_id) + host_facets = ForemanPuppet::HostPuppetFacet + .where(host_id: ::Host::Managed.reorder(nil).select(:id)) + .select(:id) + hostgroup_facets = ForemanPuppet::HostgroupPuppetFacet + .where(hostgroup_id: ::Hostgroup.unscoped.with_taxonomy_scope.reorder(nil).select(:id)) + .select(:id) + direct = ForemanPuppet::HostClass + .where(host_puppet_facet_id: host_facets) + .select(:puppetclass_id) + via_hostgroup = ForemanPuppet::HostgroupClass + .where(hostgroup_puppet_facet_id: hostgroup_facets) + .select(:puppetclass_id) + config_group_ids = ForemanPuppet::HostConfigGroup.assigned_to_taxonomy.select(:config_group_id) via_config_group = ForemanPuppet::ConfigGroupClass - .where(config_group_id: ForemanPuppet::HostConfigGroup.select(:config_group_id)) + .where(config_group_id: config_group_ids) .select(:puppetclass_id) where(id: direct).or(where(id: via_hostgroup)).or(where(id: via_config_group)) diff --git a/test/models/foreman_puppet/host_test.rb b/test/models/foreman_puppet/host_test.rb index 46319e19..0e9caf42 100644 --- a/test/models/foreman_puppet/host_test.rb +++ b/test/models/foreman_puppet/host_test.rb @@ -176,6 +176,43 @@ class HostTest < ActiveSupport::TestCase assert_not_includes completions, %(config_group = "#{config_group.name}") end + test 'limits Puppet assignment completions to the current organization' do + organization = taxonomies(:organization1) + location = taxonomies(:location1) + visible_host = FactoryBot.create( + :host, + :with_puppet_enc, + :with_puppetclass, + organization: organization, + location: location + ) + hidden_host = FactoryBot.create( + :host, + :with_puppet_enc, + :with_puppetclass, + organization: FactoryBot.create(:organization), + location: location + ) + visible_config_group = FactoryBot.create(:config_group) + hidden_config_group = FactoryBot.create(:config_group) + visible_host.puppet.config_groups << visible_config_group + hidden_host.puppet.config_groups << hidden_config_group + Organization.current = organization + Location.current = nil + + visible_puppetclass = visible_host.puppet.puppetclasses.first + hidden_puppetclass = hidden_host.puppet.puppetclasses.first + visible_puppetclasses = ::Host::Managed.complete_for("puppetclass = #{visible_puppetclass.name}") + hidden_puppetclasses = ::Host::Managed.complete_for("puppetclass = #{hidden_puppetclass.name}") + visible_config_groups = ::Host::Managed.complete_for("config_group = #{visible_config_group.name}") + hidden_config_groups = ::Host::Managed.complete_for("config_group = #{hidden_config_group.name}") + + assert_includes visible_puppetclasses, %(puppetclass = "#{visible_puppetclass.name}") + assert_not_includes hidden_puppetclasses, %(puppetclass = "#{hidden_puppetclass.name}") + assert_includes visible_config_groups, %(config_group = "#{visible_config_group.name}") + assert_not_includes hidden_config_groups, %(config_group = "#{hidden_config_group.name}") + end + test 'preserves core host value completions' do completions = as_admin { ::Host::Managed.complete_for('user.login =') } diff --git a/test/models/foreman_puppet/hostgroup_test.rb b/test/models/foreman_puppet/hostgroup_test.rb index 3c83cb73..7bcdfcc7 100644 --- a/test/models/foreman_puppet/hostgroup_test.rb +++ b/test/models/foreman_puppet/hostgroup_test.rb @@ -47,6 +47,41 @@ class HostgroupTest < ActiveSupport::TestCase assert_includes completions, %(puppetclass = "#{puppetclass.name}") end + test 'limits Puppet assignment completions to the current location' do + organization = taxonomies(:organization1) + location = taxonomies(:location1) + visible_hostgroup = FactoryBot.create( + :hostgroup, + :with_puppet_enc, + :with_puppetclass, + organizations: [organization], + locations: [location] + ) + hidden_hostgroup = FactoryBot.create( + :hostgroup, + :with_puppet_enc, + :with_puppetclass, + organizations: [organization], + locations: [FactoryBot.create(:location)] + ) + visible_config_group = visible_hostgroup.puppet.config_groups.first + hidden_config_group = hidden_hostgroup.puppet.config_groups.first + Organization.current = nil + Location.current = location + + visible_puppetclass = visible_hostgroup.puppet.puppetclasses.first + hidden_puppetclass = hidden_hostgroup.puppet.puppetclasses.first + visible_puppetclasses = ::Hostgroup.complete_for("puppetclass = #{visible_puppetclass.name}") + hidden_puppetclasses = ::Hostgroup.complete_for("puppetclass = #{hidden_puppetclass.name}") + visible_config_groups = ::Hostgroup.complete_for("config_group = #{visible_config_group.name}") + hidden_config_groups = ::Hostgroup.complete_for("config_group = #{hidden_config_group.name}") + + assert_includes visible_puppetclasses, %(puppetclass = "#{visible_puppetclass.name}") + assert_not_includes hidden_puppetclasses, %(puppetclass = "#{hidden_puppetclass.name}") + assert_includes visible_config_groups, %(config_group = "#{visible_config_group.name}") + assert_not_includes hidden_config_groups, %(config_group = "#{hidden_config_group.name}") + end + test 'searches Puppet class values assigned through a config group' do config_group = hostgroup.puppet.config_groups.first puppetclass = FactoryBot.create(:puppetclass)