chef 18.4.12-x64-mingw-ucrt → 18.5.0-x64-mingw-ucrt
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/chef.gemspec +6 -6
- data/lib/chef/client.rb +0 -15
- data/lib/chef/cookbook/chefignore.rb +4 -1
- data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
- data/lib/chef/cookbook/synchronizer.rb +2 -1
- data/lib/chef/cookbook_manifest.rb +2 -2
- data/lib/chef/file_cache.rb +17 -2
- data/lib/chef/formatters/doc.rb +1 -1
- data/lib/chef/mixin/openssl_helper.rb +1 -1
- data/lib/chef/node/attribute.rb +3 -11
- data/lib/chef/node/immutable_collections.rb +15 -8
- data/lib/chef/node/mixin/state_tracking.rb +6 -3
- data/lib/chef/policy_builder/policyfile.rb +8 -0
- data/lib/chef/provider/package/chocolatey.rb +54 -24
- data/lib/chef/provider/package/powershell.rb +1 -0
- data/lib/chef/provider/package/snap.rb +1 -0
- data/lib/chef/provider/package/zypper.rb +0 -1
- data/lib/chef/provider/service/windows.rb +0 -1
- data/lib/chef/resource/chef_client_config.rb +2 -1
- data/lib/chef/resource/chef_client_systemd_timer.rb +5 -0
- data/lib/chef/resource/chef_gem.rb +1 -1
- data/lib/chef/resource/execute.rb +8 -6
- data/lib/chef/resource/habitat_install.rb +2 -1
- data/lib/chef/resource/powershell_package.rb +4 -0
- data/lib/chef/resource/snap_package.rb +23 -0
- data/lib/chef/resource/support/client.erb +1 -1
- data/lib/chef/resource/sysctl.rb +1 -0
- data/lib/chef/version.rb +1 -1
- data/spec/functional/resource/remote_file_spec.rb +1 -1
- data/spec/integration/client/fips_spec.rb +11 -2
- data/spec/integration/client/open_ssl_spec.rb +20 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/platform_helpers.rb +20 -7
- data/spec/unit/client_spec.rb +0 -16
- data/spec/unit/file_cache_spec.rb +64 -0
- data/spec/unit/mixin/openssl_helper_spec.rb +6 -1
- data/spec/unit/provider/package/chocolatey_spec.rb +17 -12
- data/spec/unit/provider/package/windows_spec.rb +5 -5
- data/spec/unit/provider/package/zypper_spec.rb +0 -10
- metadata +10 -9
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 77d916c27d4f54717bf1b19c187381d22af18afd8c342e9a991021f79da84710
         | 
| 4 | 
            +
              data.tar.gz: 3d3c421530c1d1be2b4dfb6977a36e5442678af9a7bf9ab9a536ed0d4d89acab
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: eefdb38b46958cc9df3c528b48aff78b289b4185411c272868c3e4b79cc3c4b68bb046aaa534a282dbb0936228dce9ce8045d39a0a2ee23d270cc8f10398b212
         | 
| 7 | 
            +
              data.tar.gz: 066de3ee0964e8632c8644b7f685c2d8a7d0f512e094b0825585afc514493f0560235c8c8e1ac1b3b37b6a2f26ef78162e58f30f02c6ffcfdf2aa17e3fd6efe5
         | 
    
        data/Gemfile
    CHANGED
    
    | @@ -10,6 +10,8 @@ gem "rest-client", git: "https://github.com/chef/rest-client", branch: "jfm/ucrt | |
| 10 10 | 
             
            gem "ffi", ">= 1.15.5"
         | 
| 11 11 | 
             
            gem "chef-utils", path: File.expand_path("chef-utils", __dir__) if File.exist?(File.expand_path("chef-utils", __dir__))
         | 
| 12 12 | 
             
            gem "chef-config", path: File.expand_path("chef-config", __dir__) if File.exist?(File.expand_path("chef-config", __dir__))
         | 
| 13 | 
            +
            # required for FIPS or bundler will pick up default openssl
         | 
| 14 | 
            +
            gem "openssl", "= 3.2.0" unless Gem.platforms.any? { |platform| !platform.is_a?(String) && platform.os == "darwin" }
         | 
| 13 15 |  | 
| 14 16 | 
             
            if File.exist?(File.expand_path("chef-bin", __dir__))
         | 
| 15 17 | 
             
              # bundling in a git checkout
         | 
    
        data/chef.gemspec
    CHANGED
    
    | @@ -2,12 +2,12 @@ $:.unshift(File.dirname(__FILE__) + "/lib") | |
| 2 2 | 
             
            vs_path = File.expand_path("chef-utils/lib/chef-utils/version_string.rb", __dir__)
         | 
| 3 3 |  | 
| 4 4 | 
             
            if File.exist?(vs_path)
         | 
| 5 | 
            -
              #  | 
| 6 | 
            -
               | 
| 7 | 
            -
             | 
| 8 | 
            -
              # if the path doesn't exist then we're just in the wild gem and not in the git repo
         | 
| 9 | 
            -
              require "chef-utils/version_string"
         | 
| 5 | 
            +
              # include chef-utils/lib in the path if we're inside of chef vs. chef-utils gem
         | 
| 6 | 
            +
              # but add it to the end of the search path
         | 
| 7 | 
            +
              $: << (File.dirname(__FILE__) + "/chef-utils/lib")
         | 
| 10 8 | 
             
            end
         | 
| 9 | 
            +
            # if the path doesn't exist then we're just in the wild gem and not in the git repo
         | 
| 10 | 
            +
            require "chef-utils/version_string"
         | 
| 11 11 | 
             
            require "chef/version"
         | 
| 12 12 |  | 
| 13 13 | 
             
            Gem::Specification.new do |s|
         | 
| @@ -65,7 +65,7 @@ Gem::Specification.new do |s| | |
| 65 65 |  | 
| 66 66 | 
             
              s.add_dependency "aws-sdk-s3", "~> 1.91" # s3 recipe-url support
         | 
| 67 67 | 
             
              s.add_dependency "aws-sdk-secretsmanager", "~> 1.46"
         | 
| 68 | 
            -
              s.add_dependency "vault", "~> 0. | 
| 68 | 
            +
              s.add_dependency "vault", "~> 0.18.2" # hashi vault official client gem
         | 
| 69 69 | 
             
              s.bindir       = "bin"
         | 
| 70 70 | 
             
              s.executables  = %w{ }
         | 
| 71 71 |  | 
    
        data/lib/chef/client.rb
    CHANGED
    
    | @@ -305,8 +305,6 @@ class Chef | |
| 305 305 | 
             
                    # keep this inside the main loop to get exception backtraces
         | 
| 306 306 | 
             
                    end_profiling
         | 
| 307 307 |  | 
| 308 | 
            -
                    warn_if_eol
         | 
| 309 | 
            -
             | 
| 310 308 | 
             
                    # rebooting has to be the last thing we do, no exceptions.
         | 
| 311 309 | 
             
                    Chef::Platform::Rebooter.reboot_if_needed!(node)
         | 
| 312 310 | 
             
                  rescue Exception => run_error
         | 
| @@ -335,19 +333,6 @@ class Chef | |
| 335 333 | 
             
                # @todo make this stuff protected or private
         | 
| 336 334 | 
             
                #
         | 
| 337 335 |  | 
| 338 | 
            -
                # @api private
         | 
| 339 | 
            -
                def warn_if_eol
         | 
| 340 | 
            -
                  require_relative "version"
         | 
| 341 | 
            -
             | 
| 342 | 
            -
                  # We make a release every year so take the version you're on + 2006 and you get
         | 
| 343 | 
            -
                  # the year it goes EOL
         | 
| 344 | 
            -
                  eol_year = 2006 + Gem::Version.new(Chef::VERSION).segments.first
         | 
| 345 | 
            -
             | 
| 346 | 
            -
                  if Time.now > Time.new(eol_year, 5, 01)
         | 
| 347 | 
            -
                    logger.warn("This release of #{ChefUtils::Dist::Infra::PRODUCT} became end of life (EOL) on May 1st #{eol_year}. Please update to a supported release to receive new features, bug fixes, and security updates.")
         | 
| 348 | 
            -
                  end
         | 
| 349 | 
            -
                end
         | 
| 350 | 
            -
             | 
| 351 336 | 
             
                # @api private
         | 
| 352 337 | 
             
                def configure_formatters
         | 
| 353 338 | 
             
                  formatters_for_run.map do |formatter_name, output_path|
         | 
| @@ -50,7 +50,10 @@ class Chef | |
| 50 50 | 
             
                    ignore_globs = []
         | 
| 51 51 | 
             
                    if @ignore_file && readable_file_or_symlink?(@ignore_file)
         | 
| 52 52 | 
             
                      File.foreach(@ignore_file) do |line|
         | 
| 53 | 
            -
                         | 
| 53 | 
            +
                        unless COMMENTS_AND_WHITESPACE.match?(line)
         | 
| 54 | 
            +
                          line.strip!
         | 
| 55 | 
            +
                          ignore_globs << line
         | 
| 56 | 
            +
                        end
         | 
| 54 57 | 
             
                      end
         | 
| 55 58 | 
             
                    else
         | 
| 56 59 | 
             
                      Chef::Log.debug("No chefignore file found. No files will be ignored!")
         | 
| @@ -215,7 +215,7 @@ class Chef | |
| 215 215 | 
             
                    Dir.entries(cookbook_path).each do |top_filename|
         | 
| 216 216 | 
             
                      # Skip top-level directories starting with "."
         | 
| 217 217 | 
             
                      top_path = File.join(cookbook_path, top_filename)
         | 
| 218 | 
            -
                      next if  | 
| 218 | 
            +
                      next if top_filename.start_with?(".") && File.directory?(top_path)
         | 
| 219 219 |  | 
| 220 220 | 
             
                      # Use Find.find because it:
         | 
| 221 221 | 
             
                      # (a) returns any children, recursively
         | 
| @@ -280,8 +280,9 @@ class Chef | |
| 280 280 | 
             
                end
         | 
| 281 281 |  | 
| 282 282 | 
             
                def ensure_cookbook_paths
         | 
| 283 | 
            +
                  cookbook_path = File.join(Chef::Config[:file_cache_path], "cookbooks")
         | 
| 283 284 | 
             
                  cookbooks.each do |cookbook|
         | 
| 284 | 
            -
                    cb_dir = File.join( | 
| 285 | 
            +
                    cb_dir = File.join(cookbook_path, cookbook.name)
         | 
| 285 286 | 
             
                    cookbook.root_paths = Array(cb_dir)
         | 
| 286 287 | 
             
                  end
         | 
| 287 288 | 
             
                end
         | 
| @@ -173,9 +173,9 @@ class Chef | |
| 173 173 | 
             
                def files_for(part)
         | 
| 174 174 | 
             
                  return root_files if part.to_s == "root_files"
         | 
| 175 175 |  | 
| 176 | 
            +
                  part_match = "#{part}/"
         | 
| 176 177 | 
             
                  manifest[:all_files].select do |file|
         | 
| 177 | 
            -
                     | 
| 178 | 
            -
                    part.to_s == seg
         | 
| 178 | 
            +
                    file[:name].start_with?(part_match)
         | 
| 179 179 | 
             
                  end
         | 
| 180 180 | 
             
                end
         | 
| 181 181 |  | 
    
        data/lib/chef/file_cache.rb
    CHANGED
    
    | @@ -159,9 +159,24 @@ class Chef | |
| 159 159 | 
             
                  # [String] - An array of file cache keys matching the glob
         | 
| 160 160 | 
             
                  def find(glob_pattern)
         | 
| 161 161 | 
             
                    keys = []
         | 
| 162 | 
            -
                     | 
| 162 | 
            +
                    file_cache_dir = Chef::Util::PathHelper.escape_glob_dir(file_cache_path)
         | 
| 163 | 
            +
                    first_filename = Dir[file_cache_dir].first # directory of the cache
         | 
| 164 | 
            +
                    return keys unless first_filename
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                    # TODO: The usage of Regexp.escape and the match here is likely
         | 
| 167 | 
            +
                    # vestigial, but since it's only getting called once per method, the
         | 
| 168 | 
            +
                    # effort needed to confirm that its removal won't break something else
         | 
| 169 | 
            +
                    # isn't worth it. A task for a brave soul ;-)
         | 
| 170 | 
            +
                    regexp_pattern = /^(#{Regexp.escape(first_filename) + File::Separator}).+/
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                    files = Dir[File.join(file_cache_dir, glob_pattern)]
         | 
| 173 | 
            +
                    until files.empty?
         | 
| 174 | 
            +
                      f = files.shift
         | 
| 163 175 | 
             
                      if File.file?(f)
         | 
| 164 | 
            -
                         | 
| 176 | 
            +
                        # We remove the cache directory from the string of each entry
         | 
| 177 | 
            +
                        path_to_remove ||= f[regexp_pattern, 1]
         | 
| 178 | 
            +
                        f.delete_prefix!(path_to_remove)
         | 
| 179 | 
            +
                        keys << f
         | 
| 165 180 | 
             
                      end
         | 
| 166 181 | 
             
                    end
         | 
| 167 182 | 
             
                    keys
         | 
    
        data/lib/chef/formatters/doc.rb
    CHANGED
    
    | @@ -57,7 +57,7 @@ class Chef | |
| 57 57 | 
             
                    # Print out deprecations.
         | 
| 58 58 | 
             
                    unless deprecations.empty?
         | 
| 59 59 | 
             
                      puts_line ""
         | 
| 60 | 
            -
                      puts_line "Deprecation warnings that must be addressed before upgrading to  | 
| 60 | 
            +
                      puts_line "Deprecation warnings that must be addressed before upgrading to #{ChefUtils::Dist::Infra::PRODUCT} #{Chef::VERSION.to_i + 1}:"
         | 
| 61 61 | 
             
                      puts_line ""
         | 
| 62 62 | 
             
                      deprecations.each do |message, details|
         | 
| 63 63 | 
             
                        locations = details[:locations]
         | 
| @@ -157,7 +157,7 @@ class Chef | |
| 157 157 | 
             
                    raise TypeError, "curve must be a string" unless curve.is_a?(String)
         | 
| 158 158 | 
             
                    raise ArgumentError, "Specified curve is not available on this system" unless %w{prime256v1 secp384r1 secp521r1}.include?(curve)
         | 
| 159 159 |  | 
| 160 | 
            -
                    ::OpenSSL::PKey::EC. | 
| 160 | 
            +
                    ::OpenSSL::PKey::EC.generate(curve)
         | 
| 161 161 | 
             
                  end
         | 
| 162 162 |  | 
| 163 163 | 
             
                  # generate pem format of the public key given a private key
         | 
    
        data/lib/chef/node/attribute.rb
    CHANGED
    
    | @@ -570,7 +570,7 @@ class Chef | |
| 570 570 | 
             
                    ]
         | 
| 571 571 |  | 
| 572 572 | 
             
                    ret = components.inject(NIL) do |merged, component|
         | 
| 573 | 
            -
                      hash_only_merge!(merged, component)
         | 
| 573 | 
            +
                      component == NIL ? merged : hash_only_merge!(merged, component)
         | 
| 574 574 | 
             
                    end
         | 
| 575 575 | 
             
                    ret == NIL ? nil : ret
         | 
| 576 576 | 
             
                  end
         | 
| @@ -584,7 +584,7 @@ class Chef | |
| 584 584 | 
             
                  def merge_defaults(path)
         | 
| 585 585 | 
             
                    DEFAULT_COMPONENTS.inject(NIL) do |merged, component_ivar|
         | 
| 586 586 | 
             
                      component_value = apply_path(instance_variable_get(component_ivar), path)
         | 
| 587 | 
            -
                      deep_merge!(merged, component_value)
         | 
| 587 | 
            +
                      component_value == NIL ? merged : deep_merge!(merged, component_value)
         | 
| 588 588 | 
             
                    end
         | 
| 589 589 | 
             
                  end
         | 
| 590 590 |  | 
| @@ -597,7 +597,7 @@ class Chef | |
| 597 597 | 
             
                  def merge_overrides(path)
         | 
| 598 598 | 
             
                    OVERRIDE_COMPONENTS.inject(NIL) do |merged, component_ivar|
         | 
| 599 599 | 
             
                      component_value = apply_path(instance_variable_get(component_ivar), path)
         | 
| 600 | 
            -
                      deep_merge!(merged, component_value)
         | 
| 600 | 
            +
                      component_value == NIL ? merged : deep_merge!(merged, component_value)
         | 
| 601 601 | 
             
                    end
         | 
| 602 602 | 
             
                  end
         | 
| 603 603 |  | 
| @@ -628,10 +628,6 @@ class Chef | |
| 628 628 | 
             
                    elsif merge_onto.is_a?(Array) && merge_with.is_a?(Array)
         | 
| 629 629 | 
             
                      merge_onto |= merge_with
         | 
| 630 630 |  | 
| 631 | 
            -
                    # If merge_with is NIL, don't replace merge_onto
         | 
| 632 | 
            -
                    elsif merge_with == NIL
         | 
| 633 | 
            -
                      merge_onto
         | 
| 634 | 
            -
             | 
| 635 631 | 
             
                    # In all other cases, replace merge_onto with merge_with
         | 
| 636 632 | 
             
                    else
         | 
| 637 633 | 
             
                      if merge_with.is_a?(Hash)
         | 
| @@ -661,10 +657,6 @@ class Chef | |
| 661 657 | 
             
                      end
         | 
| 662 658 | 
             
                      merge_onto
         | 
| 663 659 |  | 
| 664 | 
            -
                    # If merge_with is NIL, don't replace merge_onto
         | 
| 665 | 
            -
                    elsif merge_with == NIL
         | 
| 666 | 
            -
                      merge_onto
         | 
| 667 | 
            -
             | 
| 668 660 | 
             
                    # In all other cases, replace merge_onto with merge_with
         | 
| 669 661 | 
             
                    else
         | 
| 670 662 | 
             
                      if merge_with.is_a?(Hash)
         | 
| @@ -33,18 +33,25 @@ class Chef | |
| 33 33 | 
             
                  end
         | 
| 34 34 |  | 
| 35 35 | 
             
                  def convert_value(value)
         | 
| 36 | 
            -
                    # The order in this case statement is *important*.
         | 
| 37 | 
            -
                    # ImmutableMash and ImmutableArray should be tested first,
         | 
| 38 | 
            -
                    # as this saves unnecessary creation of intermediate objects
         | 
| 39 36 | 
             
                    case value
         | 
| 40 | 
            -
                    when ImmutableMash, ImmutableArray
         | 
| 41 | 
            -
                      value
         | 
| 42 37 | 
             
                    when Hash
         | 
| 43 | 
            -
                      ImmutableMash | 
| 38 | 
            +
                      if ImmutableMash === value
         | 
| 39 | 
            +
                        # Save an object creation
         | 
| 40 | 
            +
                        value
         | 
| 41 | 
            +
                      else
         | 
| 42 | 
            +
                        ImmutableMash.new(value, __root__, __node__, __precedence__)
         | 
| 43 | 
            +
                      end
         | 
| 44 44 | 
             
                    when Array
         | 
| 45 | 
            -
                      ImmutableArray | 
| 45 | 
            +
                      if ImmutableArray === value
         | 
| 46 | 
            +
                        # Save an object creation
         | 
| 47 | 
            +
                        value
         | 
| 48 | 
            +
                      else
         | 
| 49 | 
            +
                        ImmutableArray.new(value, __root__, __node__, __precedence__)
         | 
| 50 | 
            +
                      end
         | 
| 46 51 | 
             
                    else
         | 
| 47 | 
            -
                       | 
| 52 | 
            +
                      # We return any already frozen strings, since that's common over the course of a run.
         | 
| 53 | 
            +
                      # Check `frozen?` first since that's faster than a Class comparison
         | 
| 54 | 
            +
                      value.frozen? && String === value ? value : safe_dup(value).freeze
         | 
| 48 55 | 
             
                    end
         | 
| 49 56 | 
             
                  end
         | 
| 50 57 |  | 
| @@ -37,7 +37,8 @@ class Chef | |
| 37 37 | 
             
                    def [](*args)
         | 
| 38 38 | 
             
                      ret = super
         | 
| 39 39 | 
             
                      key = args.first
         | 
| 40 | 
            -
                      next_path = [ __path__, convert_key(key) ].flatten | 
| 40 | 
            +
                      next_path = [ __path__, convert_key(key) ].flatten
         | 
| 41 | 
            +
                      next_path.compact!
         | 
| 41 42 | 
             
                      copy_state_to(ret, next_path)
         | 
| 42 43 | 
             
                    end
         | 
| 43 44 |  | 
| @@ -45,7 +46,8 @@ class Chef | |
| 45 46 | 
             
                      ret = super
         | 
| 46 47 | 
             
                      key = args.first
         | 
| 47 48 | 
             
                      value = args.last
         | 
| 48 | 
            -
                      next_path = [ __path__, convert_key(key) ].flatten | 
| 49 | 
            +
                      next_path = [ __path__, convert_key(key) ].flatten
         | 
| 50 | 
            +
                      next_path.compact!
         | 
| 49 51 | 
             
                      send_attribute_changed_event(next_path, value)
         | 
| 50 52 | 
             
                      copy_state_to(ret, next_path)
         | 
| 51 53 | 
             
                    end
         | 
| @@ -77,7 +79,8 @@ class Chef | |
| 77 79 | 
             
                    end
         | 
| 78 80 |  | 
| 79 81 | 
             
                    def send_reset_cache(path = nil, key = nil)
         | 
| 80 | 
            -
                      next_path = [ path, key ].flatten | 
| 82 | 
            +
                      next_path = [ path, key ].flatten
         | 
| 83 | 
            +
                      next_path.compact!
         | 
| 81 84 | 
             
                      __root__.reset_cache(next_path.first) if !__root__.nil? && __root__.respond_to?(:reset_cache)
         | 
| 82 85 | 
             
                    end
         | 
| 83 86 |  | 
| @@ -132,6 +132,9 @@ class Chef | |
| 132 132 |  | 
| 133 133 | 
             
                    node.consume_external_attrs(ohai_data, json_attribs)
         | 
| 134 134 |  | 
| 135 | 
            +
                    # Preserve the fall back to loading an unencrypted data bag item if the item we're trying to load isn't actually a vault item.
         | 
| 136 | 
            +
                    set_databag_fallback
         | 
| 137 | 
            +
             | 
| 135 138 | 
             
                    setup_run_list_override
         | 
| 136 139 |  | 
| 137 140 | 
             
                    expand_run_list
         | 
| @@ -191,6 +194,11 @@ class Chef | |
| 191 194 | 
             
                    run_context
         | 
| 192 195 | 
             
                  end
         | 
| 193 196 |  | 
| 197 | 
            +
                  # Preserve the fall back to loading an unencrypted data bag item if the item we're trying to load isn't actually a vault item.
         | 
| 198 | 
            +
                  def set_databag_fallback
         | 
| 199 | 
            +
                    node.default["chef-vault"]["databag_fallback"] = ChefUtils.kitchen?(node)
         | 
| 200 | 
            +
                  end
         | 
| 201 | 
            +
             | 
| 194 202 | 
             
                  # Sets `run_list` on the node from the policy, sets `roles` and `recipes`
         | 
| 195 203 | 
             
                  # attributes on the node accordingly.
         | 
| 196 204 | 
             
                  #
         | 
| @@ -144,7 +144,11 @@ class Chef | |
| 144 144 | 
             
                    def check_resource_semantics!; end
         | 
| 145 145 |  | 
| 146 146 | 
             
                    def get_choco_version
         | 
| 147 | 
            -
                       | 
| 147 | 
            +
                      # We need a different way to get the version than by simply calling "choco --version".
         | 
| 148 | 
            +
                      # If the license file is installed (for business customers) but not the Chocolatey.Extension (because you're using the choco resource to install it)
         | 
| 149 | 
            +
                      # then you get a license error. This method bypasses that by getting the version from the exe directly instead of invoking it.
         | 
| 150 | 
            +
                      # deprecated: @get_choco_version ||= powershell_exec!("#{choco_exe} --version").result
         | 
| 151 | 
            +
                      @get_choco_version ||= powershell_exec!("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").result
         | 
| 148 152 | 
             
                    end
         | 
| 149 153 |  | 
| 150 154 | 
             
                    # Choco V2 uses 'Search' for remote repositories and 'List' for local packages
         | 
| @@ -167,22 +171,34 @@ class Chef | |
| 167 171 | 
             
                      true
         | 
| 168 172 | 
             
                    end
         | 
| 169 173 |  | 
| 170 | 
            -
                    #  | 
| 171 | 
            -
                    # | 
| 172 | 
            -
                    #  | 
| 173 | 
            -
                    #  | 
| 174 | 
            -
                    #  | 
| 174 | 
            +
                    # Find the set of packages to ask the chocolatey server about
         | 
| 175 | 
            +
                    #
         | 
| 176 | 
            +
                    # if walk_resource_tree is true, this finds _all_ of the packages that
         | 
| 177 | 
            +
                    # we have referenced anywhere in our recipes - this is so we can
         | 
| 178 | 
            +
                    # attempt to query them all in a single transaction.  However,
         | 
| 179 | 
            +
                    # currently we don't do that - see the comment on available_packages
         | 
| 180 | 
            +
                    # for details of the why, but the TL;DR is that the public chocolatey
         | 
| 181 | 
            +
                    # servers do not support `or` type queries properly.
         | 
| 182 | 
            +
                    #
         | 
| 183 | 
            +
                    # If walk_resource_tree is false, we don't do any of that - we just filter
         | 
| 184 | 
            +
                    # the package list based on cache data.  This is the default due to reasons
         | 
| 185 | 
            +
                    # explained in the comment on available_packages - the goal is to eventually
         | 
| 186 | 
            +
                    # turn this back on, hence the default false parameter here.
         | 
| 175 187 | 
             
                    #
         | 
| 176 188 | 
             
                    # @return [Array] List of chocolatey packages referenced in the run list
         | 
| 177 | 
            -
                    def collect_package_requests(ignore_list: [])
         | 
| 189 | 
            +
                    def collect_package_requests(ignore_list: [], walk_resource_tree: false)
         | 
| 178 190 | 
             
                      return ["*"] if new_resource.bulk_query || Chef::Config[:always_use_bulk_chocolatey_package_list]
         | 
| 179 191 |  | 
| 180 | 
            -
                       | 
| 181 | 
            -
             | 
| 182 | 
            -
             | 
| 192 | 
            +
                      if walk_resource_tree
         | 
| 193 | 
            +
                        # Get to the root of the resource collection
         | 
| 194 | 
            +
                        rc = run_context.parent_run_context || run_context
         | 
| 195 | 
            +
                        rc = rc.parent_run_context while rc.parent_run_context
         | 
| 183 196 |  | 
| 184 | 
            -
             | 
| 185 | 
            -
             | 
| 197 | 
            +
                        package_collection = package_name_array
         | 
| 198 | 
            +
                        package_collection += nested_package_resources(rc.resource_collection)
         | 
| 199 | 
            +
                      else
         | 
| 200 | 
            +
                        package_collection = package_name_array
         | 
| 201 | 
            +
                      end
         | 
| 186 202 | 
             
                      # downcase the array and uniq.  sorted for easier testing...
         | 
| 187 203 | 
             
                      package_collection.uniq.sort.filter { |pkg| !ignore_list.include?(pkg) }
         | 
| 188 204 | 
             
                    end
         | 
| @@ -339,22 +355,33 @@ class Chef | |
| 339 355 | 
             
                        @@choco_available_packages[new_resource.list_options] = {}
         | 
| 340 356 | 
             
                      end
         | 
| 341 357 |  | 
| 342 | 
            -
                      #  | 
| 343 | 
            -
                      #  | 
| 358 | 
            +
                      # This would previously grab 25 packages at a time, which previously worked - however,
         | 
| 359 | 
            +
                      # upstream changed and it turns out this was only working by accident - see
         | 
| 360 | 
            +
                      # https://github.com/chocolatey/choco/issues/2116 for this.  So the TL;DR ends up
         | 
| 361 | 
            +
                      # being that this can be re-enabled when the chocolatey server actually supports an
         | 
| 362 | 
            +
                      # or operator.  So it makes sense to leave the logic here for this split, while we
         | 
| 363 | 
            +
                      # work with upstream to get this to be a working feature there
         | 
| 364 | 
            +
                      #
         | 
| 365 | 
            +
                      # Foot guns: there is a --id-starts-with for chocolatey, which you'd think would work,
         | 
| 366 | 
            +
                      # but that actually fails on public chocolatey as well, because it seems to do the filtering
         | 
| 367 | 
            +
                      # locally. Which means it too will omit a lot of results (this is also corroborated by
         | 
| 368 | 
            +
                      # the 2116 issue above).
         | 
| 344 369 | 
             
                      #
         | 
| 345 | 
            -
                      #  | 
| 346 | 
            -
                      #  | 
| 370 | 
            +
                      # collect_package_requests, however, continues to be useful here because it filters
         | 
| 371 | 
            +
                      # the already cached things from the list.  However, for now it will no longer walk the
         | 
| 372 | 
            +
                      # resource tree until 2116 can be sorted out.  When we regain that ability, we should
         | 
| 373 | 
            +
                      # re-evaluate this, since it does save a LOT of API requests!
         | 
| 347 374 | 
             
                      collect_package_requests(
         | 
| 348 375 | 
             
                        ignore_list: @@choco_available_packages[new_resource.list_options].keys
         | 
| 349 | 
            -
                      ). | 
| 376 | 
            +
                      ).each do |pkg_set|
         | 
| 350 377 | 
             
                        available_versions =
         | 
| 351 378 | 
             
                          begin
         | 
| 352 379 | 
             
                          cmd = [ query_command, "-r" ]
         | 
| 353 380 |  | 
| 354 381 | 
             
                          # Chocolatey doesn't actually take a wildcard for this query, however
         | 
| 355 382 | 
             
                          # it will return all packages when using '*' as a query
         | 
| 356 | 
            -
                          unless pkg_set ==  | 
| 357 | 
            -
                            cmd  | 
| 383 | 
            +
                          unless pkg_set == "*"
         | 
| 384 | 
            +
                            cmd << pkg_set
         | 
| 358 385 | 
             
                          end
         | 
| 359 386 | 
             
                          cmd += common_options
         | 
| 360 387 | 
             
                          cmd.push( new_resource.list_options ) if new_resource.list_options
         | 
| @@ -383,10 +410,12 @@ class Chef | |
| 383 410 | 
             
                    #
         | 
| 384 411 | 
             
                    # @return [Hash] name-to-version mapping of installed packages
         | 
| 385 412 | 
             
                    def installed_packages
         | 
| 386 | 
            -
                       | 
| 387 | 
            -
             | 
| 388 | 
            -
                       | 
| 413 | 
            +
                      # Logic here must be either use_choco_list is false _and_ always_use_choco_list is
         | 
| 414 | 
            +
                      # falsy, since the global overrides the local
         | 
| 415 | 
            +
                      if new_resource.use_choco_list == false && !Chef::Config[:always_use_choco_list]
         | 
| 389 416 | 
             
                        installed_packages_via_disk
         | 
| 417 | 
            +
                      else
         | 
| 418 | 
            +
                        installed_packages_via_choco
         | 
| 390 419 | 
             
                      end
         | 
| 391 420 | 
             
                    end
         | 
| 392 421 |  | 
| @@ -413,8 +442,8 @@ class Chef | |
| 413 442 | 
             
                        # that contains all possible package folders, and so we push our
         | 
| 414 443 | 
             
                        # guess to the front as an optimization.
         | 
| 415 444 | 
             
                        target_dirs << targets.first.downcase if targets.length == 1
         | 
| 416 | 
            -
                        if targets. | 
| 417 | 
            -
                          target_dirs << targets
         | 
| 445 | 
            +
                        if targets.is_a?(String)
         | 
| 446 | 
            +
                          target_dirs << targets.downcase
         | 
| 418 447 | 
             
                        end
         | 
| 419 448 | 
             
                        target_dirs += get_local_pkg_dirs(choco_lib_path)
         | 
| 420 449 | 
             
                        fetch_package_versions(choco_lib_path, target_dirs, targets)
         | 
| @@ -465,6 +494,7 @@ class Chef | |
| 465 494 | 
             
                    # Fetch the local package versions from chocolatey
         | 
| 466 495 | 
             
                    def fetch_package_versions(base_dir, target_dirs, targets)
         | 
| 467 496 | 
             
                      pkg_versions = {}
         | 
| 497 | 
            +
                      targets = [targets] if targets.is_a?(String)
         | 
| 468 498 | 
             
                      target_dirs.each do |dir|
         | 
| 469 499 | 
             
                        pkg_versions.merge!(get_pkg_data(::File.join(base_dir, dir)))
         | 
| 470 500 | 
             
                        # return early if we found the single package version we were looking for
         | 
| @@ -127,6 +127,7 @@ class Chef | |
| 127 127 | 
             
                      command.push("-RequiredVersion #{version}") if version
         | 
| 128 128 | 
             
                      command.push("-Source #{new_resource.source}") if new_resource.source && cmdlet_name =~ Regexp.union(/Install-Package/, /Find-Package/)
         | 
| 129 129 | 
             
                      command.push("-SkipPublisherCheck") if new_resource.skip_publisher_check && cmdlet_name !~ /Find-Package/
         | 
| 130 | 
            +
                      command.push("-AllowClobber") if new_resource.allow_clobber
         | 
| 130 131 | 
             
                      if new_resource.options && cmdlet_name !~ Regexp.union(/Get-Package/, /Find-Package/)
         | 
| 131 132 | 
             
                        new_resource.options.each do |arg|
         | 
| 132 133 | 
             
                          command.push(arg) unless command.include?(arg)
         | 
| @@ -146,7 +146,6 @@ class Chef | |
| 146 146 | 
             
                        if md = line.match(/^(\S*)\s+\|\s+(\S+)\s+\|\s+(\S+)\s+\|\s+(\S+)\s+\|\s+(\S+)\s+\|\s+(.*)$/)
         | 
| 147 147 | 
             
                          (status, name, type, version, arch, repo) = [ md[1], md[2], md[3], md[4], md[5], md[6] ]
         | 
| 148 148 | 
             
                          next if version == "Version" # header
         | 
| 149 | 
            -
                          next if name != package_name
         | 
| 150 149 |  | 
| 151 150 | 
             
                          # sometimes even though we request a specific version in the search string above and have match exact, we wind up
         | 
| 152 151 | 
             
                          # with other versions in the output, particularly getting the installed version when downgrading.
         | 
| @@ -74,7 +74,6 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service | |
| 74 74 | 
             
                  current_resource.run_as_user(config_info.service_start_name)    if config_info.service_start_name
         | 
| 75 75 | 
             
                  current_resource.display_name(config_info.display_name)         if config_info.display_name
         | 
| 76 76 | 
             
                  current_resource.delayed_start(current_delayed_start)           if current_delayed_start
         | 
| 77 | 
            -
                  current_resource.description(config_info.description)           if new_resource.description
         | 
| 78 77 | 
             
                end
         | 
| 79 78 |  | 
| 80 79 | 
             
                current_resource
         | 
| @@ -198,7 +198,8 @@ class Chef | |
| 198 198 | 
             
                    introduced: "17.3"
         | 
| 199 199 |  | 
| 200 200 | 
             
                  property :minimal_ohai, [true, false],
         | 
| 201 | 
            -
                    description: "Run a minimal set of Ohai plugins providing data necessary for the execution of #{ChefUtils::Dist::Infra::PRODUCT}'s built-in resources. Setting this to true will skip many large and time consuming data sets such as `cloud` or `packages`. Setting this  | 
| 201 | 
            +
                    description: "Run a minimal set of Ohai plugins providing data necessary for the execution of #{ChefUtils::Dist::Infra::PRODUCT}'s built-in resources. Setting this to true will skip many large and time consuming data sets such as `cloud` or `packages`. Setting this to true may break cookbooks that assume all Ohai data will be present.",
         | 
| 202 | 
            +
                    default: false
         | 
| 202 203 |  | 
| 203 204 | 
             
                  property :start_handlers, Array,
         | 
| 204 205 | 
             
                    description: %q(An array of hashes that contain a report handler class and the arguments to pass to that class on initialization. The hash should include `class` and `argument` keys where `class` is a String and `argument` is an array of quoted String values. For example: `[{'class' => 'MyHandler', %w('"argument1"', '"argument2"')}]`),
         | 
| @@ -103,6 +103,10 @@ class Chef | |
| 103 103 | 
             
                    coerce: proc { |x| Integer(x) },
         | 
| 104 104 | 
             
                    callbacks: { "should be a positive Integer" => proc { |v| v > 0 } }
         | 
| 105 105 |  | 
| 106 | 
            +
                  property :service_umask, [Integer, String],
         | 
| 107 | 
            +
                    description: "Fix umask for hardened systems that have a changed default umask. This changes the chef-client umask so any files or folders are created with new umask. Recommend setting to stand install default of 0022.",
         | 
| 108 | 
            +
                    introduced: "18.5"
         | 
| 109 | 
            +
             | 
| 106 110 | 
             
                  action :add, description: "Add a systemd timer that runs #{ChefUtils::Dist::Infra::PRODUCT}." do
         | 
| 107 111 | 
             
                    systemd_unit "#{new_resource.job_name}.service" do
         | 
| 108 112 | 
             
                      content service_content
         | 
| @@ -175,6 +179,7 @@ class Chef | |
| 175 179 | 
             
                        "Install" => { "WantedBy" => "multi-user.target" },
         | 
| 176 180 | 
             
                      }
         | 
| 177 181 |  | 
| 182 | 
            +
                      unit["Service"]["UMask"] = new_resource.service_umask if new_resource.service_umask
         | 
| 178 183 | 
             
                      unit["Service"]["ConditionACPower"] = "true" unless new_resource.run_on_battery
         | 
| 179 184 | 
             
                      unit["Service"]["CPUQuota"] = "#{new_resource.cpu_quota}%" if new_resource.cpu_quota
         | 
| 180 185 | 
             
                      unit["Service"]["Environment"] = new_resource.environment.collect { |k, v| "\"#{k}=#{v}\"" } unless new_resource.environment.empty?
         | 
| @@ -442,14 +442,14 @@ class Chef | |
| 442 442 | 
             
                    NetworkService have this right when running as a service. This is necessary
         | 
| 443 443 | 
             
                    even if the user is an Administrator.
         | 
| 444 444 |  | 
| 445 | 
            -
                    This right can be added and checked in a recipe using this example:
         | 
| 445 | 
            +
                    This right can be added and checked in a recipe using this example (will not take effect in the same Chef run):
         | 
| 446 446 |  | 
| 447 447 | 
             
                    ```ruby
         | 
| 448 | 
            -
                     | 
| 449 | 
            -
             | 
| 450 | 
            -
             | 
| 451 | 
            -
             | 
| 452 | 
            -
                     | 
| 448 | 
            +
                    windows_user_privilege 'add assign token privilege' do
         | 
| 449 | 
            +
                      principal '<user>'
         | 
| 450 | 
            +
                      privilege 'SeAssignPrimaryTokenPrivilege'
         | 
| 451 | 
            +
                      action :add
         | 
| 452 | 
            +
                    end
         | 
| 453 453 | 
             
                    ```
         | 
| 454 454 |  | 
| 455 455 | 
             
                    The following example shows how to run `mkdir test_dir` from a Chef Infra Client
         | 
| @@ -492,9 +492,11 @@ class Chef | |
| 492 492 |  | 
| 493 493 | 
             
                    **Run a command with an external input file**:
         | 
| 494 494 |  | 
| 495 | 
            +
                    ```ruby
         | 
| 495 496 | 
             
                    execute 'md5sum' do
         | 
| 496 497 | 
             
                      input File.read(__FILE__)
         | 
| 497 498 | 
             
                    end
         | 
| 499 | 
            +
                    ```
         | 
| 498 500 | 
             
                  EXAMPLES
         | 
| 499 501 |  | 
| 500 502 | 
             
                  # The ResourceGuardInterpreter wraps a resource's guards in another resource.  That inner resource
         | 
| @@ -127,6 +127,7 @@ class Chef | |
| 127 127 | 
             
                      remote_file ::File.join(Chef::Config[:file_cache_path], "hab-install.sh") do
         | 
| 128 128 | 
             
                        source new_resource.install_url
         | 
| 129 129 | 
             
                        sensitive true
         | 
| 130 | 
            +
                        mode 0755
         | 
| 130 131 | 
             
                      end
         | 
| 131 132 |  | 
| 132 133 | 
             
                      execute "installing with hab-install.sh" do
         | 
| @@ -235,7 +236,7 @@ class Chef | |
| 235 236 | 
             
                    end
         | 
| 236 237 |  | 
| 237 238 | 
             
                    def hab_command
         | 
| 238 | 
            -
                      cmd = " | 
| 239 | 
            +
                      cmd = "#{Chef::Config[:file_cache_path]}/hab-install.sh"
         | 
| 239 240 | 
             
                      cmd << " -v #{new_resource.hab_version} " if new_resource.hab_version
         | 
| 240 241 | 
             
                      cmd << " -t x86_64-linux-kernel2" if node["kernel"]["release"].to_i < 3
         | 
| 241 242 | 
             
                      cmd
         | 
| @@ -44,6 +44,10 @@ class Chef | |
| 44 44 | 
             
                    description: "Skip validating module author.",
         | 
| 45 45 | 
             
                    default: false, introduced: "14.3", desired_state: false
         | 
| 46 46 |  | 
| 47 | 
            +
                  property :allow_clobber,  [TrueClass, FalseClass],
         | 
| 48 | 
            +
                    description: "Overrides warning messages about installation conflicts about existing commands on a computer.",
         | 
| 49 | 
            +
                    default: false, introduced: "18.5"
         | 
| 50 | 
            +
             | 
| 47 51 | 
             
                end
         | 
| 48 52 | 
             
              end
         | 
| 49 53 | 
             
            end
         | 
| @@ -26,6 +26,29 @@ class Chef | |
| 26 26 |  | 
| 27 27 | 
             
                  description "Use the **snap_package** resource to manage snap packages on Debian and Ubuntu platforms."
         | 
| 28 28 | 
             
                  introduced "15.0"
         | 
| 29 | 
            +
                  examples <<~DOC
         | 
| 30 | 
            +
                  **Install a package**
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  ```ruby
         | 
| 33 | 
            +
                  snap_package 'hello'
         | 
| 34 | 
            +
                  ```
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  **Upgrade a package**
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  ```ruby
         | 
| 39 | 
            +
                  snap_package 'hello' do
         | 
| 40 | 
            +
                    action :upgrade
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                  ```
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  **Install a package with classic confinement**
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  ```ruby
         | 
| 47 | 
            +
                  snap_package 'hello' do
         | 
| 48 | 
            +
                    options 'classic'
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                  ```
         | 
| 51 | 
            +
                  DOC
         | 
| 29 52 |  | 
| 30 53 | 
             
                  allowed_actions :install, :upgrade, :remove, :purge
         | 
| 31 54 |  | 
| @@ -10,7 +10,6 @@ | |
| 10 10 | 
             
                  @https_proxy
         | 
| 11 11 | 
             
                  @ftp_proxy
         | 
| 12 12 | 
             
                  @log_level
         | 
| 13 | 
            -
                  @minimal_ohai
         | 
| 14 13 | 
             
                  @named_run_list
         | 
| 15 14 | 
             
                  @no_proxy
         | 
| 16 15 | 
             
                  @pid_file
         | 
| @@ -22,6 +21,7 @@ | |
| 22 21 | 
             
            <% next if instance_variable_get(prop).nil? || instance_variable_get(prop).empty? -%>
         | 
| 23 22 | 
             
            <%=prop.delete_prefix("@") %> <%= instance_variable_get(prop).inspect %>
         | 
| 24 23 | 
             
            <% end -%>
         | 
| 24 | 
            +
            minimal_ohai <%= @minimal_ohai.inspect %>
         | 
| 25 25 | 
             
            <%# ohai_disabled_plugins and ohai_optional_plugins properties don't match the config value perfectly-%>
         | 
| 26 26 | 
             
            <% %w(@ohai_disabled_plugins
         | 
| 27 27 | 
             
                  @ohai_optional_plugins).each do |prop| -%>
         | 
    
        data/lib/chef/resource/sysctl.rb
    CHANGED
    
    | @@ -103,6 +103,7 @@ class Chef | |
| 103 103 | 
             
                  property :comment, [Array, String],
         | 
| 104 104 | 
             
                    description: "Comments, placed above the resource setting in the generated file. For multi-line comments, use an array of strings, one per line.",
         | 
| 105 105 | 
             
                    default: [],
         | 
| 106 | 
            +
                    desired_state: false,
         | 
| 106 107 | 
             
                    introduced: "15.8"
         | 
| 107 108 |  | 
| 108 109 | 
             
                  property :conf_dir, String,
         | 
    
        data/lib/chef/version.rb
    CHANGED
    
    
| @@ -245,7 +245,7 @@ describe Chef::Resource::RemoteFile do | |
| 245 245 | 
             
                      end
         | 
| 246 246 | 
             
                    end
         | 
| 247 247 |  | 
| 248 | 
            -
                    context "when the  | 
| 248 | 
            +
                    context "when the file is only accessible as a specific alternate identity" do
         | 
| 249 249 | 
             
                      let(:windows_nonadmin_user) { "chefremfile2" }
         | 
| 250 250 | 
             
                      let(:windows_nonadmin_user_password) { "j82ajfxK3;2Xe2" }
         | 
| 251 251 | 
             
                      include_context "a non-admin Windows user"
         | 
| @@ -9,12 +9,21 @@ describe "chef-client fips" do | |
| 9 9 | 
             
              after { OpenSSL.fips_mode = false }
         | 
| 10 10 |  | 
| 11 11 | 
             
              # For non-FIPS OSes/builds of Ruby, enabling FIPS should error
         | 
| 12 | 
            -
              example "Error enabling fips_mode if FIPS not linked",  | 
| 12 | 
            +
              example "Error enabling fips_mode if FIPS not linked", :fips_mode_negative_test do
         | 
| 13 13 | 
             
                expect { enable_fips }.to raise_error(OpenSSL::OpenSSLError)
         | 
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 | 
            +
              example "Do not error on MD5 if not fips_mode", :fips_mode_negative_test do
         | 
| 17 | 
            +
                expect { OpenSSL::Digest.new("MD5", "test string for digesting") }.not_to raise_error
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 16 20 | 
             
              # For FIPS OSes/builds of Ruby, enabling FIPS should not error
         | 
| 17 | 
            -
              example "Do not error enabling fips_mode if FIPS linked",  | 
| 21 | 
            +
              example "Do not error enabling fips_mode if FIPS linked", :fips_mode_test do
         | 
| 18 22 | 
             
                expect { enable_fips }.not_to raise_error
         | 
| 19 23 | 
             
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              example "Error on MD5 if fips_mode", :fips_mode_test do
         | 
| 26 | 
            +
                enable_fips
         | 
| 27 | 
            +
                expect { OpenSSL::Digest.new("MD5", "test string for digesting") }.to raise_error(OpenSSL::Digest::DigestError)
         | 
| 28 | 
            +
              end
         | 
| 20 29 | 
             
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "openssl checks" do
         | 
| 4 | 
            +
              let(:openssl_version_default) do
         | 
| 5 | 
            +
                if windows?
         | 
| 6 | 
            +
                  "1.0.2zi"
         | 
| 7 | 
            +
                elsif macos?
         | 
| 8 | 
            +
                  "1.1.1m"
         | 
| 9 | 
            +
                else
         | 
| 10 | 
            +
                  "3.0.9"
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              %w{version library_version}.each do |method|
         | 
| 15 | 
            +
                # macOS just picks up its own for some reason, maybe it circumvents a build step
         | 
| 16 | 
            +
                example "check #{method}", not_supported_on_macos: true do
         | 
| 17 | 
            +
                  expect(OpenSSL.const_get("OPENSSL_#{method.upcase}")).to match(openssl_version_default), "OpenSSL doesn't match omnibus_overrides.rb"
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -138,7 +138,8 @@ RSpec.configure do |config| | |
| 138 138 |  | 
| 139 139 | 
             
              config.filter_run_excluding skip_buildkite: true if ENV["BUILDKITE"]
         | 
| 140 140 |  | 
| 141 | 
            -
              config.filter_run_excluding  | 
| 141 | 
            +
              config.filter_run_excluding fips_mode_test: true unless fips_mode_build?
         | 
| 142 | 
            +
              config.filter_run_excluding fips_mode_negative_test: true # disable all fips_mode negative tests
         | 
| 142 143 | 
             
              # Skip fips on windows
         | 
| 143 144 | 
             
              # config.filter_run_excluding :fips_mode if windows?
         | 
| 144 145 |  | 
| @@ -180,6 +181,7 @@ RSpec.configure do |config| | |
| 180 181 | 
             
              config.filter_run_excluding aes_256_gcm_only: true unless aes_256_gcm?
         | 
| 181 182 | 
             
              config.filter_run_excluding broken: true
         | 
| 182 183 | 
             
              config.filter_run_excluding not_wpar: true unless wpar?
         | 
| 184 | 
            +
              config.filter_run_excluding not_supported_on_s390x: true unless s390x?
         | 
| 183 185 | 
             
              config.filter_run_excluding not_supported_under_fips: true if fips?
         | 
| 184 186 | 
             
              config.filter_run_excluding rhel: true unless rhel?
         | 
| 185 187 | 
             
              config.filter_run_excluding rhel6: true unless rhel6?
         | 
| @@ -67,10 +67,10 @@ end | |
| 67 67 |  | 
| 68 68 | 
             
            def win32_os_version
         | 
| 69 69 | 
             
              @win32_os_version ||= begin
         | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 70 | 
            +
                                      wmi = WmiLite::Wmi.new
         | 
| 71 | 
            +
                                      host = wmi.first_of("Win32_OperatingSystem")
         | 
| 72 | 
            +
                                      host["version"]
         | 
| 73 | 
            +
                                    end
         | 
| 74 74 | 
             
            end
         | 
| 75 75 |  | 
| 76 76 | 
             
            def windows_powershell_dsc?
         | 
| @@ -80,7 +80,7 @@ def windows_powershell_dsc? | |
| 80 80 | 
             
              begin
         | 
| 81 81 | 
             
                wmi = WmiLite::Wmi.new("root/microsoft/windows/desiredstateconfiguration")
         | 
| 82 82 | 
             
                lcm = wmi.query("SELECT * FROM meta_class WHERE __this ISA 'MSFT_DSCLocalConfigurationManager'")
         | 
| 83 | 
            -
                supports_dsc = !! | 
| 83 | 
            +
                supports_dsc = !!lcm
         | 
| 84 84 | 
             
              rescue WmiLite::WmiException
         | 
| 85 85 | 
             
              end
         | 
| 86 86 | 
             
              supports_dsc
         | 
| @@ -95,7 +95,7 @@ end | |
| 95 95 |  | 
| 96 96 | 
             
            # detects if the hardware is 64-bit (evaluates to true in "WOW64" mode in a 32-bit app on a 64-bit system)
         | 
| 97 97 | 
             
            def windows64?
         | 
| 98 | 
            -
              windows? && ( | 
| 98 | 
            +
              windows? && (ENV["PROCESSOR_ARCHITECTURE"] == "AMD64" || ENV["PROCESSOR_ARCHITEW6432"] == "AMD64")
         | 
| 99 99 | 
             
            end
         | 
| 100 100 |  | 
| 101 101 | 
             
            # detects if the hardware is 32-bit
         | 
| @@ -175,6 +175,10 @@ def wpar? | |
| 175 175 | 
             
              !((ohai[:virtualization] || {})[:wpar_no].nil?)
         | 
| 176 176 | 
             
            end
         | 
| 177 177 |  | 
| 178 | 
            +
            def s390x?
         | 
| 179 | 
            +
              RUBY_PLATFORM.include?("s390x")
         | 
| 180 | 
            +
            end
         | 
| 181 | 
            +
             | 
| 178 182 | 
             
            def supports_cloexec?
         | 
| 179 183 | 
             
              Fcntl.const_defined?(:F_SETFD) && Fcntl.const_defined?(:FD_CLOEXEC)
         | 
| 180 184 | 
             
            end
         | 
| @@ -224,7 +228,15 @@ def aes_256_gcm? | |
| 224 228 | 
             
            end
         | 
| 225 229 |  | 
| 226 230 | 
             
            def fips_mode_build?
         | 
| 227 | 
            -
               | 
| 231 | 
            +
              if ENV.include?("BUILDKITE_LABEL") # try keying directly off Buildkite environments
         | 
| 232 | 
            +
                # regex version of chef/chef-foundation:.expeditor/release.omnibus.yml:fips-platforms
         | 
| 233 | 
            +
                [/el-.*-x86_64/, /el-.*-ppc64/, /el-.*aarch/, /ubuntu-/, /windows-/, /amazon-2/].any? do |os_arch|
         | 
| 234 | 
            +
                  ENV["BUILDKITE_LABEL"].match?(os_arch)
         | 
| 235 | 
            +
                end
         | 
| 236 | 
            +
              else
         | 
| 237 | 
            +
                # if you're testing your local build
         | 
| 238 | 
            +
                OpenSSL::OPENSSL_FIPS
         | 
| 239 | 
            +
              end
         | 
| 228 240 | 
             
            end
         | 
| 229 241 |  | 
| 230 242 | 
             
            def fips?
         | 
| @@ -233,6 +245,7 @@ end | |
| 233 245 |  | 
| 234 246 | 
             
            class HttpHelper
         | 
| 235 247 | 
             
              extend Ohai::Mixin::HttpHelper
         | 
| 248 | 
            +
             | 
| 236 249 | 
             
              def self.logger
         | 
| 237 250 | 
             
                Chef::Log
         | 
| 238 251 | 
             
              end
         | 
    
        data/spec/unit/client_spec.rb
    CHANGED
    
    | @@ -384,22 +384,6 @@ describe Chef::Client do | |
| 384 384 | 
             
                end
         | 
| 385 385 | 
             
              end
         | 
| 386 386 |  | 
| 387 | 
            -
              describe "eol release warning" do
         | 
| 388 | 
            -
                it "warns when running an EOL release" do
         | 
| 389 | 
            -
                  stub_const("Chef::VERSION", 15)
         | 
| 390 | 
            -
                  allow(Time).to receive(:now).and_return(Time.new(2021, 5, 1, 5))
         | 
| 391 | 
            -
                  expect(logger).to receive(:warn).with(/This release of.*became end of life \(EOL\) on May 1st 2021/)
         | 
| 392 | 
            -
                  client.warn_if_eol
         | 
| 393 | 
            -
                end
         | 
| 394 | 
            -
             | 
| 395 | 
            -
                it "does not warn when running an non-EOL release" do
         | 
| 396 | 
            -
                  stub_const("Chef::VERSION", 15)
         | 
| 397 | 
            -
                  allow(Time).to receive(:now).and_return(Time.new(2021, 4, 31))
         | 
| 398 | 
            -
                  expect(logger).to_not receive(:warn).with(/became end of life/)
         | 
| 399 | 
            -
                  client.warn_if_eol
         | 
| 400 | 
            -
                end
         | 
| 401 | 
            -
              end
         | 
| 402 | 
            -
             | 
| 403 387 | 
             
              describe "authentication protocol selection" do
         | 
| 404 388 | 
             
                context "when FIPS is disabled" do
         | 
| 405 389 | 
             
                  before do
         | 
| @@ -94,7 +94,71 @@ describe Chef::FileCache do | |
| 94 94 | 
             
                it "searches for cached files by globbing" do
         | 
| 95 95 | 
             
                  expect(Chef::FileCache.find("snappy/**/*")).to eq(%w{snappy/patter})
         | 
| 96 96 | 
             
                end
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
              describe "#find handles regex-unsafe unix paths" do
         | 
| 100 | 
            +
                before(:each) do
         | 
| 101 | 
            +
                  # Dir.mktmpdir doesn't allow regex unsafe characters (the nerve!), so we'll have to fake file lookups
         | 
| 102 | 
            +
                  @file_cache_path = "/tmp/[foo* ^bar]"
         | 
| 103 | 
            +
                  escaped_file_cache_path = '/tmp/\[foo\* ^bar\]'
         | 
| 104 | 
            +
                  Chef::Config[:file_cache_path] = @file_cache_path
         | 
| 105 | 
            +
                  allow(Chef::Util::PathHelper).to receive(:escape_glob_dir).and_return(escaped_file_cache_path)
         | 
| 106 | 
            +
                  allow(Dir).to receive(:[]).with(File.join(escaped_file_cache_path, "snappy/**/*")).and_return([
         | 
| 107 | 
            +
                    File.join(@file_cache_path, "snappy"),
         | 
| 108 | 
            +
                    File.join(@file_cache_path, "snappy", "patter"),
         | 
| 109 | 
            +
                  ])
         | 
| 110 | 
            +
                  allow(Dir).to receive(:[]).with(escaped_file_cache_path).and_return([
         | 
| 111 | 
            +
                    @file_cache_path,
         | 
| 112 | 
            +
                  ])
         | 
| 113 | 
            +
                  [
         | 
| 114 | 
            +
                    File.join(@file_cache_path, "snappy", "patter"),
         | 
| 115 | 
            +
                    File.join(@file_cache_path, "whiz", "bang"),
         | 
| 116 | 
            +
                  ].each do |f|
         | 
| 117 | 
            +
                    allow(File).to receive(:file?).with(f).and_return(true)
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
                  [
         | 
| 120 | 
            +
                    File.join(@file_cache_path, "snappy"),
         | 
| 121 | 
            +
                    File.join(@file_cache_path, "whiz"),
         | 
| 122 | 
            +
                  ].each do |f|
         | 
| 123 | 
            +
                    allow(File).to receive(:file?).with(f).and_return(false)
         | 
| 124 | 
            +
                  end
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                it "searches for cached files by globbing" do
         | 
| 128 | 
            +
                  expect(Chef::FileCache.find("snappy/**/*")).to eq(%w{snappy/patter})
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
              end
         | 
| 97 131 |  | 
| 132 | 
            +
              describe "#find handles Windows paths" do
         | 
| 133 | 
            +
                before(:each) do
         | 
| 134 | 
            +
                  allow(ChefUtils).to receive(:windows?).and_return(true)
         | 
| 135 | 
            +
                  @file_cache_path = 'C:\tmp\fakecache'
         | 
| 136 | 
            +
                  escaped_file_cache_path = "C:\\tmp\\fakecache"
         | 
| 137 | 
            +
                  Chef::Config[:file_cache_path] = @file_cache_path
         | 
| 138 | 
            +
                  allow(Chef::Util::PathHelper).to receive(:escape_glob_dir).and_return(escaped_file_cache_path)
         | 
| 139 | 
            +
                  allow(Dir).to receive(:[]).with(File.join(escaped_file_cache_path, "snappy/**/*")).and_return([
         | 
| 140 | 
            +
                    File.join(@file_cache_path, "snappy"),
         | 
| 141 | 
            +
                    File.join(@file_cache_path, "snappy", "patter"),
         | 
| 142 | 
            +
                  ])
         | 
| 143 | 
            +
                  allow(Dir).to receive(:[]).with(escaped_file_cache_path).and_return([
         | 
| 144 | 
            +
                    @file_cache_path,
         | 
| 145 | 
            +
                  ])
         | 
| 146 | 
            +
                  [
         | 
| 147 | 
            +
                    File.join(@file_cache_path, "snappy", "patter"),
         | 
| 148 | 
            +
                    File.join(@file_cache_path, "whiz", "bang"),
         | 
| 149 | 
            +
                  ].each do |f|
         | 
| 150 | 
            +
                    allow(File).to receive(:file?).with(f).and_return(true)
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
                  [
         | 
| 153 | 
            +
                    File.join(@file_cache_path, "snappy"),
         | 
| 154 | 
            +
                    File.join(@file_cache_path, "whiz"),
         | 
| 155 | 
            +
                  ].each do |f|
         | 
| 156 | 
            +
                    allow(File).to receive(:file?).with(f).and_return(false)
         | 
| 157 | 
            +
                  end
         | 
| 158 | 
            +
                end
         | 
| 159 | 
            +
                it "searches for cached files by globbing" do
         | 
| 160 | 
            +
                  expect(Chef::FileCache.find("snappy/**/*")).to eq(%w{snappy/patter})
         | 
| 161 | 
            +
                end
         | 
| 98 162 | 
             
              end
         | 
| 99 163 |  | 
| 100 164 | 
             
              describe "when checking for the existence of a file" do
         | 
| @@ -92,7 +92,12 @@ describe Chef::Mixin::OpenSSLHelper do | |
| 92 92 |  | 
| 93 93 | 
             
                context "When the dhparam.pem file does exist, and does contain a vaild dhparam key" do
         | 
| 94 94 | 
             
                  it "returns true" do
         | 
| 95 | 
            -
                     | 
| 95 | 
            +
                    # bumped this from 256 to 1024 because OpenSSL 3.x will enforce
         | 
| 96 | 
            +
                    # size
         | 
| 97 | 
            +
                    #      OpenSSL::PKey::PKeyError:
         | 
| 98 | 
            +
                    #       EVP_PKEY_paramgen: modulus too small
         | 
| 99 | 
            +
                    # need to double check that the mixin itself doesn't allow smaller
         | 
| 100 | 
            +
                    @dhparam_file.puts(::OpenSSL::PKey::DH.new(1024).to_pem)
         | 
| 96 101 | 
             
                    @dhparam_file.close
         | 
| 97 102 | 
             
                    expect(instance.dhparam_pem_valid?(@dhparam_file.path)).to be_truthy
         | 
| 98 103 | 
             
                  end
         | 
| @@ -36,9 +36,9 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do | |
| 36 36 | 
             
              # installed packages (ConEmu is upgradable)
         | 
| 37 37 | 
             
              let(:local_list_stdout) do
         | 
| 38 38 | 
             
                <<~EOF
         | 
| 39 | 
            -
                  Chocolatey v0.9.9. | 
| 40 | 
            -
                  chocolatey|0.9.9. | 
| 41 | 
            -
                  ConEmu|15.10.25. | 
| 39 | 
            +
                  Chocolatey v0.9.9.10
         | 
| 40 | 
            +
                  chocolatey|0.9.9.12
         | 
| 41 | 
            +
                  ConEmu|15.10.25.2
         | 
| 42 42 | 
             
                EOF
         | 
| 43 43 | 
             
              end
         | 
| 44 44 |  | 
| @@ -47,10 +47,10 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do | |
| 47 47 | 
             
                allow(provider).to receive(:choco_exe).and_return(choco_exe)
         | 
| 48 48 | 
             
                local_list_obj = double(stdout: local_list_stdout)
         | 
| 49 49 | 
             
                allow(provider).to receive(:shell_out_compacted!).with(choco_exe, "list", "-l", "-r", { returns: [0, 2], timeout: timeout }).and_return(local_list_obj)
         | 
| 50 | 
            -
                allow(provider).to receive(:powershell_exec!).with("#{choco_exe}  | 
| 50 | 
            +
                allow(provider).to receive(:powershell_exec!).with("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").and_return(double(result: "2.1.0"))
         | 
| 51 51 | 
             
                # Mock the local file system choco queries
         | 
| 52 52 | 
             
                allow(provider).to receive(:get_local_pkg_dirs).and_return(%w{chocolatey ConEmu})
         | 
| 53 | 
            -
                allow(provider).to receive(: | 
| 53 | 
            +
                allow(provider).to receive(:fetch_package_versions).and_return({ "chocolatey" => "0.9.9.11", "conemu" => "15.10.25.0" })
         | 
| 54 54 | 
             
              end
         | 
| 55 55 |  | 
| 56 56 | 
             
              after(:each) do
         | 
| @@ -70,10 +70,13 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do | |
| 70 70 | 
             
                  munin-node|1.6.1.20130823
         | 
| 71 71 | 
             
                EOF
         | 
| 72 72 | 
             
                remote_list_obj = double(stdout: remote_list_stdout)
         | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 73 | 
            +
             | 
| 74 | 
            +
                package_names.each do |pkg|
         | 
| 75 | 
            +
                  if args
         | 
| 76 | 
            +
                    allow(provider).to receive(:shell_out_compacted!).with(choco_exe, provider.query_command, "-r", *([pkg] + args), { returns: [0, 2], timeout: timeout }).and_return(remote_list_obj)
         | 
| 77 | 
            +
                  else
         | 
| 78 | 
            +
                    allow(provider).to receive(:shell_out_compacted!).with(choco_exe, provider.query_command, "-r", pkg, { returns: [0, 2], timeout: timeout }).and_return(remote_list_obj)
         | 
| 79 | 
            +
                  end
         | 
| 77 80 | 
             
                end
         | 
| 78 81 | 
             
              end
         | 
| 79 82 |  | 
| @@ -89,12 +92,12 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do | |
| 89 92 |  | 
| 90 93 | 
             
              describe "choco searches change with the version" do
         | 
| 91 94 | 
             
                it "Choco V1 uses List" do
         | 
| 92 | 
            -
                  allow(provider).to receive(:powershell_exec!).with("#{choco_exe}  | 
| 95 | 
            +
                  allow(provider).to receive(:powershell_exec!).with("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").and_return(double(result: "1.4.0"))
         | 
| 93 96 | 
             
                  expect(provider.query_command).to eql("list")
         | 
| 94 97 | 
             
                end
         | 
| 95 98 |  | 
| 96 99 | 
             
                it "Choco V2 uses Search" do
         | 
| 97 | 
            -
                  allow(provider).to receive(:powershell_exec!).with("#{choco_exe}  | 
| 100 | 
            +
                  allow(provider).to receive(:powershell_exec!).with("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").and_return(double(result: "2.1.0"))
         | 
| 98 101 | 
             
                  expect(provider.query_command).to eql("search")
         | 
| 99 102 | 
             
                end
         | 
| 100 103 | 
             
              end
         | 
| @@ -168,6 +171,7 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do | |
| 168 171 |  | 
| 169 172 | 
             
                it "should load and downcase names in the installed_packages hash (with disk provider)" do
         | 
| 170 173 | 
             
                  new_resource.use_choco_list(false)
         | 
| 174 | 
            +
                  provider.invalidate_cache
         | 
| 171 175 | 
             
                  provider.load_current_resource
         | 
| 172 176 | 
             
                  expect(provider.send(:installed_packages)).to eql(
         | 
| 173 177 | 
             
                    { "chocolatey" => "0.9.9.11", "conemu" => "15.10.25.0" }
         | 
| @@ -176,9 +180,10 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do | |
| 176 180 |  | 
| 177 181 | 
             
                it "should load and downcase names in the installed_packages hash (with choco list provider)" do
         | 
| 178 182 | 
             
                  new_resource.use_choco_list(true)
         | 
| 183 | 
            +
                  provider.invalidate_cache
         | 
| 179 184 | 
             
                  provider.load_current_resource
         | 
| 180 185 | 
             
                  expect(provider.send(:installed_packages)).to eql(
         | 
| 181 | 
            -
                    { "chocolatey" => "0.9.9. | 
| 186 | 
            +
                    { "chocolatey" => "0.9.9.12", "conemu" => "15.10.25.2" }
         | 
| 182 187 | 
             
                  )
         | 
| 183 188 | 
             
                end
         | 
| 184 189 |  | 
| @@ -106,27 +106,27 @@ describe Chef::Provider::Package::Windows, :windows_only do | |
| 106 106 | 
             
                    provider.package_provider
         | 
| 107 107 | 
             
                  end
         | 
| 108 108 |  | 
| 109 | 
            -
                  it "sets the package provider to MSI if the  | 
| 109 | 
            +
                  it "sets the package provider to MSI if the installer type is :msi" do
         | 
| 110 110 | 
             
                    allow(provider).to receive(:installer_type).and_return(:msi)
         | 
| 111 111 | 
             
                    expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::MSI)
         | 
| 112 112 | 
             
                  end
         | 
| 113 113 |  | 
| 114 | 
            -
                  it "sets the package provider to Exe if the  | 
| 114 | 
            +
                  it "sets the package provider to Exe if the installer type is :inno" do
         | 
| 115 115 | 
             
                    allow(provider).to receive(:installer_type).and_return(:inno)
         | 
| 116 116 | 
             
                    expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
         | 
| 117 117 | 
             
                  end
         | 
| 118 118 |  | 
| 119 | 
            -
                  it "sets the package provider to Exe if the  | 
| 119 | 
            +
                  it "sets the package provider to Exe if the installer type is :nsis" do
         | 
| 120 120 | 
             
                    allow(provider).to receive(:installer_type).and_return(:nsis)
         | 
| 121 121 | 
             
                    expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
         | 
| 122 122 | 
             
                  end
         | 
| 123 123 |  | 
| 124 | 
            -
                  it "sets the package provider to Exe if the  | 
| 124 | 
            +
                  it "sets the package provider to Exe if the installer type is :wise" do
         | 
| 125 125 | 
             
                    allow(provider).to receive(:installer_type).and_return(:wise)
         | 
| 126 126 | 
             
                    expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
         | 
| 127 127 | 
             
                  end
         | 
| 128 128 |  | 
| 129 | 
            -
                  it "sets the package provider to Exe if the  | 
| 129 | 
            +
                  it "sets the package provider to Exe if the installer type is :installshield" do
         | 
| 130 130 | 
             
                    allow(provider).to receive(:installer_type).and_return(:installshield)
         | 
| 131 131 | 
             
                    expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
         | 
| 132 132 | 
             
                  end
         | 
| @@ -491,14 +491,4 @@ describe Chef::Provider::Package::Zypper do | |
| 491 491 | 
             
                  provider.remove_package(%w{emacs vim}, ["1.0", "2.0"])
         | 
| 492 492 | 
             
                end
         | 
| 493 493 | 
             
              end
         | 
| 494 | 
            -
             | 
| 495 | 
            -
              describe "resolve_available_version" do
         | 
| 496 | 
            -
                it "should return correct version if multiple packages are shown" do
         | 
| 497 | 
            -
                  status = double(stdout: "S  | Name                     | Type    | Version             | Arch   | Repository\n---+--------------------------+---------+---------------------+--------+-------------------------------------------------------------\n   | apache2-mod_wsgi         | package | 4.7.1-150400.3.3.1  | x86_64 | Update repository with updates from SUSE Linux Enterprise 15\n   | apache2-mod_wsgi         | package | 4.7.1-150400.1.52   | x86_64 | Main Repository\ni+ | apache2-mod_wsgi-python3 | package | 4.5.18-150000.4.6.1 | x86_64 | Update repository with updates from SUSE Linux Enterprise 15\nv  | apache2-mod_wsgi-python3 | package | 4.5.18-4.3.1        | x86_64 | Main Repository\n", exitstatus: 0)
         | 
| 498 | 
            -
             | 
| 499 | 
            -
                  allow(provider).to receive(:shell_out_compacted!).and_return(status)
         | 
| 500 | 
            -
                  result = provider.send(:resolve_available_version, "apache2-mod_wsgi-python3", nil)
         | 
| 501 | 
            -
                  expect(result).to eq("4.5.18-150000.4.6.1")
         | 
| 502 | 
            -
                end
         | 
| 503 | 
            -
              end
         | 
| 504 494 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: chef
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 18. | 
| 4 | 
            +
              version: 18.5.0
         | 
| 5 5 | 
             
            platform: x64-mingw-ucrt
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Adam Jacob
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 11 | 
            +
            date: 2024-06-26 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: chef-config
         | 
| @@ -16,28 +16,28 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - '='
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: 18. | 
| 19 | 
            +
                    version: 18.5.0
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - '='
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: 18. | 
| 26 | 
            +
                    version: 18.5.0
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: chef-utils
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 31 | 
             
                - - '='
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version: 18. | 
| 33 | 
            +
                    version: 18.5.0
         | 
| 34 34 | 
             
              type: :runtime
         | 
| 35 35 | 
             
              prerelease: false
         | 
| 36 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 37 | 
             
                requirements:
         | 
| 38 38 | 
             
                - - '='
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version: 18. | 
| 40 | 
            +
                    version: 18.5.0
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 42 | 
             
              name: train-core
         | 
| 43 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -536,14 +536,14 @@ dependencies: | |
| 536 536 | 
             
                requirements:
         | 
| 537 537 | 
             
                - - "~>"
         | 
| 538 538 | 
             
                  - !ruby/object:Gem::Version
         | 
| 539 | 
            -
                    version:  | 
| 539 | 
            +
                    version: 0.18.2
         | 
| 540 540 | 
             
              type: :runtime
         | 
| 541 541 | 
             
              prerelease: false
         | 
| 542 542 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 543 543 | 
             
                requirements:
         | 
| 544 544 | 
             
                - - "~>"
         | 
| 545 545 | 
             
                  - !ruby/object:Gem::Version
         | 
| 546 | 
            -
                    version:  | 
| 546 | 
            +
                    version: 0.18.2
         | 
| 547 547 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 548 548 | 
             
              name: win32-api
         | 
| 549 549 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -2655,6 +2655,7 @@ files: | |
| 2655 2655 | 
             
            - spec/integration/client/exit_code_spec.rb
         | 
| 2656 2656 | 
             
            - spec/integration/client/fips_spec.rb
         | 
| 2657 2657 | 
             
            - spec/integration/client/ipv6_spec.rb
         | 
| 2658 | 
            +
            - spec/integration/client/open_ssl_spec.rb
         | 
| 2658 2659 | 
             
            - spec/integration/compliance/compliance_spec.rb
         | 
| 2659 2660 | 
             
            - spec/integration/ohai/ohai_spec.rb
         | 
| 2660 2661 | 
             
            - spec/integration/recipes/accumulator_spec.rb
         | 
| @@ -3271,7 +3272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 3271 3272 | 
             
                - !ruby/object:Gem::Version
         | 
| 3272 3273 | 
             
                  version: '0'
         | 
| 3273 3274 | 
             
            requirements: []
         | 
| 3274 | 
            -
            rubygems_version: 3.3. | 
| 3275 | 
            +
            rubygems_version: 3.3.26
         | 
| 3275 3276 | 
             
            signing_key: 
         | 
| 3276 3277 | 
             
            specification_version: 4
         | 
| 3277 3278 | 
             
            summary: A systems integration framework, built to bring the benefits of configuration
         |