commit e0910b7ef2cfb7196f4d883355858a15f5a129a5
Author: Michael Moll <kvedulv@kvedulv.de>
Date:   Fri Jun 8 13:24:27 2018 +0200

    Fixes #23857 - Fix Performance/InefficientHashSearch cop

diff --git a/app/controllers/api/v2/base_controller.rb b/app/controllers/api/v2/base_controller.rb
index b316cdcee..b605653e4 100644
--- a/app/controllers/api/v2/base_controller.rb
+++ b/app/controllers/api/v2/base_controller.rb
@@ -126,10 +126,10 @@ module Api
           if v.is_a?(Array)
             association_name_ids = "#{k.singularize}_ids"
             association_name_names = "#{k.singularize}_names"
-            if resource_class.instance_methods.map(&:to_s).include?(association_name_ids) && v.any? && v.all? { |a| a.keys.include?("id") }
+            if resource_class.instance_methods.map(&:to_s).include?(association_name_ids) && v.any? && v.all? { |a| a.key?("id") }
               params[model_name][association_name_ids] = v.map { |a| a["id"] }
               params[model_name].delete(k)
-            elsif resource_class.instance_methods.map(&:to_s).include?(association_name_names) && v.any? && v.all? { |a| a.keys.include?("name") }
+            elsif resource_class.instance_methods.map(&:to_s).include?(association_name_names) && v.any? && v.all? { |a| a.key?("name") }
               params[model_name][association_name_names] = v.map { |a| a["name"] }
               params[model_name].delete(k)
             end
diff --git a/app/controllers/concerns/api/import_puppetclasses_common_controller.rb b/app/controllers/concerns/api/import_puppetclasses_common_controller.rb
index 09f36910c..bb1dd701d 100644
--- a/app/controllers/concerns/api/import_puppetclasses_common_controller.rb
+++ b/app/controllers/concerns/api/import_puppetclasses_common_controller.rb
@@ -58,7 +58,7 @@ module Api::ImportPuppetclassesCommonController
       @changed  = @importer.changes
 
       # check if environemnt id passed in URL is name of NEW environment in puppetmaster that doesn't exist in db
-      if @environment || (@changed['new'].keys.include?(@env_id) && (@environment ||= OpenStruct.new(:name => @env_id)))
+      if @environment || (@changed['new'].key?(@env_id) && (@environment ||= OpenStruct.new(:name => @env_id)))
         # only return :keys equal to @environment in @changed hash
         ["new", "obsolete", "updated", "ignored"].each do |kind|
           @changed[kind].slice!(@environment.name) unless @changed[kind].empty?
@@ -101,7 +101,7 @@ module Api::ImportPuppetclassesCommonController
   end
 
   def find_required_puppet_proxy
-    id = params.keys.include?('smart_proxy_id') ? params['smart_proxy_id'] : params['id']
+    id = params.key?('smart_proxy_id') ? params['smart_proxy_id'] : params['id']
     @smart_proxy = SmartProxy.authorized(:view_smart_proxies).find(id)
     unless @smart_proxy && SmartProxy.with_features("Puppet").pluck("smart_proxies.id").include?(@smart_proxy.id)
       not_found _('No proxy found to import classes from, ensure that the smart proxy has the Puppet feature enabled.')
@@ -110,7 +110,7 @@ module Api::ImportPuppetclassesCommonController
   end
 
   def get_environment_id
-    @env_id = if params.keys.include?('environment_id')
+    @env_id = if params.key?('environment_id')
                 params['environment_id']
               elsif controller_name == 'environments' && params['id'].present?
                 params['id']
diff --git a/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb b/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb
index d7b2fdbd3..8c2f6197e 100644
--- a/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb
+++ b/app/controllers/concerns/api/v2/lookup_keys_common_controller.rb
@@ -22,18 +22,18 @@ module Api::V2::LookupKeysCommonController
   end
 
   def smart_variable_id?
-    params.keys.include?('smart_variable_id') || controller_name.match(/smart_variables/)
+    params.key?('smart_variable_id') || controller_name.match(/smart_variables/)
   end
 
   def smart_class_parameter_id?
-    params.keys.include?('smart_class_parameter_id') || controller_name.match(/smart_class_parameters/)
+    params.key?('smart_class_parameter_id') || controller_name.match(/smart_class_parameters/)
   end
 
   [Puppetclass, Environment, Host::Base, Hostgroup].each do |model|
     model_string = model.to_s.split('::').first.downcase
 
     define_method("#{model_string}_id?") do
-      params.keys.include?("#{model_string}_id")
+      params.key?("#{model_string}_id")
     end
 
     define_method("find_#{model_string}") do
@@ -48,7 +48,7 @@ module Api::V2::LookupKeysCommonController
   end
 
   def find_smart_variable
-    id = params.keys.include?('smart_variable_id') ? params['smart_variable_id'] : params['id']
+    id = params.key?('smart_variable_id') ? params['smart_variable_id'] : params['id']
     @smart_variable   = VariableLookupKey.authorized(:view_external_variables).smart_variables.find_by_id(id.to_i) if id.to_i > 0
     @smart_variable ||= begin
                           puppet_cond = { :puppetclass_id => @puppetclass.id } if @puppetclass
@@ -70,7 +70,7 @@ module Api::V2::LookupKeysCommonController
   end
 
   def find_smart_class_parameter
-    id = params.keys.include?('smart_class_parameter_id') ? params['smart_class_parameter_id'] : params['id']
+    id = params.key?('smart_class_parameter_id') ? params['smart_class_parameter_id'] : params['id']
     @smart_class_parameter = PuppetclassLookupKey.authorized(:view_external_parameters).smart_class_parameters.find_by_id(id.to_i) if id.to_i > 0
     @smart_class_parameter ||= begin
                                  puppet_cond = { 'environment_classes.puppetclass_id'=> @puppetclass.id } if @puppetclass
@@ -121,9 +121,9 @@ module Api::V2::LookupKeysCommonController
     if (@smarts && @smart && !@smarts.find_by_id(@smart.id)) || (@smarts && !@smart)
       obj = smart_variable_id? ? "Smart variable" : "Smart class parameter"
       id = if smart_variable_id?
-             params.keys.include?('smart_variable_id') ? params['smart_variable_id'] : params['id']
+             params.key?('smart_variable_id') ? params['smart_variable_id'] : params['id']
            else
-             params.keys.include?('smart_class_parameter_id') ? params['smart_variable_id'] : params['id']
+             params.key?('smart_class_parameter_id') ? params['smart_variable_id'] : params['id']
            end
       not_found "#{obj} not found by id '#{id}'"
     end
diff --git a/app/models/auth_sources/auth_source_ldap.rb b/app/models/auth_sources/auth_source_ldap.rb
index f03af798d..a3913a5a0 100644
--- a/app/models/auth_sources/auth_source_ldap.rb
+++ b/app/models/auth_sources/auth_source_ldap.rb
@@ -199,7 +199,7 @@ class AuthSourceLdap < AuthSource
 
   def attributes_values(entry)
     Hash[required_ldap_attributes.merge(optional_ldap_attributes).map do |name, value|
-      next if value.blank? || (entry[value].blank? && optional_ldap_attributes.keys.include?(name))
+      next if value.blank? || (entry[value].blank? && optional_ldap_attributes.key?(name))
       if name.eql? :avatar
         [:avatar_hash, store_avatar(entry[value].first)]
       else
diff --git a/app/models/concerns/orchestration/compute.rb b/app/models/concerns/orchestration/compute.rb
index 36ab891ed..13dced2f9 100644
--- a/app/models/concerns/orchestration/compute.rb
+++ b/app/models/concerns/orchestration/compute.rb
@@ -27,7 +27,7 @@ module Orchestration::Compute
   end
 
   def compute_provides?(attr)
-    compute? && compute_resource.provided_attributes.keys.include?(attr)
+    compute? && compute_resource.provided_attributes.key?(attr)
   end
 
   def vm_name
@@ -148,13 +148,13 @@ module Orchestration::Compute
 
   def setComputeIP
     attrs = compute_resource.provided_attributes
-    if attrs.keys.include?(:ip) || attrs.keys.include?(:ip6)
+    if attrs.key?(:ip) || attrs.key?(:ip6)
       logger.info "Waiting for #{name} to become ready"
       compute_resource.vm_ready vm
       logger.info "waiting for instance to acquire ip address"
       vm.wait_for do
-        (attrs.keys.include?(:ip) && self.send(attrs[:ip]).present?) ||
-          (attrs.keys.include?(:ip6) && self.send(attrs[:ip6]).present?) ||
+        (attrs.key?(:ip) && self.send(attrs[:ip]).present?) ||
+          (attrs.key?(:ip6) && self.send(attrs[:ip6]).present?) ||
           self.ip_addresses.present?
       end
     end
diff --git a/app/models/host/base.rb b/app/models/host/base.rb
index 02d1b7ba7..c52bd93cc 100644
--- a/app/models/host/base.rb
+++ b/app/models/host/base.rb
@@ -242,7 +242,7 @@ module Host
         taxonomy_class = taxonomy.classify.constantize
         taxonomy_fact = Setting["#{taxonomy}_fact"]
 
-        if taxonomy_fact.present? && facts.keys.include?(taxonomy_fact)
+        if taxonomy_fact.present? && facts.key?(taxonomy_fact)
           taxonomy_from_fact = taxonomy_class.find_by_title(facts[taxonomy_fact].to_s)
         else
           default_taxonomy = taxonomy_class.find_by_title(Setting["default_#{taxonomy}"])
diff --git a/app/models/subnet.rb b/app/models/subnet.rb
index d29e5e072..8215af987 100644
--- a/app/models/subnet.rb
+++ b/app/models/subnet.rb
@@ -234,7 +234,7 @@ class Subnet < ApplicationRecord
       errors.add(:from, _("must be specified if to is defined"))   if from.blank?
       errors.add(:to,   _("must be specified if from is defined")) if to.blank?
     end
-    return if errors.keys.include?(:from) || errors.keys.include?(:to)
+    return if errors.key?(:from) || errors.key?(:to)
     errors.add(:from, _("does not belong to subnet"))     if from.present? && !self.contains?(f=IPAddr.new(from))
     errors.add(:to, _("does not belong to subnet"))       if to.present?   && !self.contains?(t=IPAddr.new(to))
     errors.add(:from, _("can't be bigger than to range")) if from.present? && t.present? && f > t
@@ -256,7 +256,7 @@ class Subnet < ApplicationRecord
 
   def ensure_ip_addrs_valid
     IP_FIELDS.each do |f|
-      errors.add(f, _("is invalid")) if (send(f).present? || REQUIRED_IP_FIELDS.include?(f)) && !validate_ip(send(f)) && !errors.keys.include?(f)
+      errors.add(f, _("is invalid")) if (send(f).present? || REQUIRED_IP_FIELDS.include?(f)) && !validate_ip(send(f)) && !errors.key?(f)
     end
   end
 
diff --git a/lib/foreman/logging.rb b/lib/foreman/logging.rb
index 38c84977a..ee64a48b0 100644
--- a/lib/foreman/logging.rb
+++ b/lib/foreman/logging.rb
@@ -76,7 +76,7 @@ module Foreman
       options.assert_valid_keys :level, :logger
       logger_name = options[:logger] || 'app'
       level       = options[:level] || :warn
-      unless ::Logging::LEVELS.keys.include?(level.to_s)
+      unless ::Logging::LEVELS.key?(level.to_s)
         raise "Unexpected log level #{level}, expected one of #{::Logging::LEVELS.keys}"
       end
       # send class, message and stack as structured fields in addition to message string
diff --git a/test/controllers/api/v2/domains_controller_test.rb b/test/controllers/api/v2/domains_controller_test.rb
index 297cde72f..867fba79f 100644
--- a/test/controllers/api/v2/domains_controller_test.rb
+++ b/test/controllers/api/v2/domains_controller_test.rb
@@ -99,7 +99,7 @@ class Api::V2::DomainsControllerTest < ActionController::TestCase
     # assert child nodes are included in response'
     NODES = ["locations", "organizations", "parameters", "subnets"]
     NODES.sort.each do |node|
-      assert show_response.keys.include?(node), "'#{node}' child node should be in response but was not"
+      assert show_response.key?(node), "'#{node}' child node should be in response but was not"
     end
   end
 
diff --git a/test/controllers/api/v2/locations_controller_test.rb b/test/controllers/api/v2/locations_controller_test.rb
index eaa739fb4..4d4e6592b 100755
--- a/test/controllers/api/v2/locations_controller_test.rb
+++ b/test/controllers/api/v2/locations_controller_test.rb
@@ -22,7 +22,7 @@ class Api::V2::LocationsControllerTest < ActionController::TestCase
              "provisioning_templates", "domains", "ptables", "realms", "environments", "hostgroups",
              "organizations", "parameters"].sort
     NODES.each do |node|
-      assert show_response.keys.include?(node), "'#{node}' child node should be in response but was not"
+      assert show_response.key?(node), "'#{node}' child node should be in response but was not"
     end
   end
 
diff --git a/test/controllers/api/v2/realms_controller_test.rb b/test/controllers/api/v2/realms_controller_test.rb
index 2f33d49b0..31bff750d 100644
--- a/test/controllers/api/v2/realms_controller_test.rb
+++ b/test/controllers/api/v2/realms_controller_test.rb
@@ -83,7 +83,7 @@ class Api::V2::RealmsControllerTest < ActionController::TestCase
     # assert child nodes are included in response'
     NODES = ["locations", "organizations"]
     NODES.sort.each do |node|
-      assert show_response.keys.include?(node), "'#{node}' child node should be in response but was not"
+      assert show_response.key?(node), "'#{node}' child node should be in response but was not"
     end
   end
 end
diff --git a/test/models/concerns/exportable_test.rb b/test/models/concerns/exportable_test.rb
index d8f5dd7b1..0bcc37d70 100644
--- a/test/models/concerns/exportable_test.rb
+++ b/test/models/concerns/exportable_test.rb
@@ -113,10 +113,10 @@ class ExportableTest < ActiveSupport::TestCase
   end
 
   test '#exportable_attributes does not include child class attrs' do
-    refute SampleSubnet.exportable_attributes.keys.include?('domain')
+    refute SampleSubnet.exportable_attributes.key?('domain')
   end
 
   test '#to_export includes own class exportables' do
-    assert @subnet_domain.to_export.keys.include?('domain')
+    assert @subnet_domain.to_export.key?('domain')
   end
 end
diff --git a/test/models/image_test.rb b/test/models/image_test.rb
index 36e0b6b9e..40bb8a5dd 100644
--- a/test/models/image_test.rb
+++ b/test/models/image_test.rb
@@ -7,7 +7,7 @@ class ImageTest < ActiveSupport::TestCase
     image = FactoryBot.build(:image, :uuid => "bar")
     ComputeResource.any_instance.stubs(:image_exists?).returns(false)
     image.valid? # trigger validations
-    assert image.errors.messages.keys.include?(:uuid)
+    assert image.errors.messages.key?(:uuid)
   end
 
   test "image name is unique per resource and os" do
diff --git a/test/models/nic_test.rb b/test/models/nic_test.rb
index fefaa221a..f74c94472 100644
--- a/test/models/nic_test.rb
+++ b/test/models/nic_test.rb
@@ -26,19 +26,19 @@ class NicTest < ActiveSupport::TestCase
   test "should fail on invalid mac" do
     i = Nic::Base.new :mac => "abccddeeff", :host => FactoryBot.create(:host, :managed)
     assert !i.valid?
-    assert i.errors.keys.include?(:mac)
+    assert i.errors.key?(:mac)
   end
 
   test "should be valid with 64-bit mac address" do
     i = Nic::Base.new :mac => "babbccddeeff00112233445566778899aabbccdd", :host => FactoryBot.create(:host)
     assert i.valid?
-    assert !i.errors.keys.include?(:mac)
+    assert !i.errors.key?(:mac)
   end
 
   test "should fail on invalid dns name" do
     i = Nic::Managed.new :mac => "dabbccddeeff", :host => FactoryBot.create(:host), :name => "invalid_dns_name"
     assert !i.valid?
-    assert i.errors.keys.include?(:name)
+    assert i.errors.key?(:name)
   end
 
   test "should fix mac address" do
diff --git a/test/models/orchestration_test.rb b/test/models/orchestration_test.rb
index 7eb4ae02a..44981d6ec 100644
--- a/test/models/orchestration_test.rb
+++ b/test/models/orchestration_test.rb
@@ -161,7 +161,7 @@ class OrchestrationTest < ActiveSupport::TestCase
     end
 
     test "we can retrieve registered methods" do
-      assert @klass.rebuild_methods.keys.include? :rebuild_test
+      assert @klass.rebuild_methods.key?(:rebuild_test)
     end
 
     test "we cannot override already subscribed methods" do
diff --git a/test/models/puppetclass_test.rb b/test/models/puppetclass_test.rb
index 439bd7e19..11e2ff9f2 100644
--- a/test/models/puppetclass_test.rb
+++ b/test/models/puppetclass_test.rb
@@ -179,7 +179,7 @@ class PuppetclassTest < ActiveSupport::TestCase
     }
 
     refute klass.update(attributes)
-    assert klass.errors.messages.keys.include?(:"lookup_keys.lookup_values.value")
+    assert klass.errors.messages.key?(:"lookup_keys.lookup_values.value")
   end
 
   context "search in puppetclasses" do
diff --git a/test/unit/puppet_fact_parser_test.rb b/test/unit/puppet_fact_parser_test.rb
index ba6dd84a1..1c770aef1 100644
--- a/test/unit/puppet_fact_parser_test.rb
+++ b/test/unit/puppet_fact_parser_test.rb
@@ -11,7 +11,7 @@ class PuppetFactsParserTest < ActiveSupport::TestCase
   test "should return list of interfaces" do
     assert importer.interfaces.present?
     assert_not_nil importer.suggested_primary_interface(FactoryBot.build(:host))
-    assert importer.interfaces.keys.include?(importer.suggested_primary_interface(FactoryBot.build(:host)).first)
+    assert importer.interfaces.key?(importer.suggested_primary_interface(FactoryBot.build(:host)).first)
   end
 
   test "should parse virtual interfaces as vlan interfaces" do
