diff options
author | Stuart Preston <stuart@chef.io> | 2018-10-26 12:16:12 +0100 |
---|---|---|
committer | Stuart Preston <stuart@chef.io> | 2018-10-26 12:16:12 +0100 |
commit | 6ff2109f0d05f0b25467d603d1fbff81052d3dd9 (patch) | |
tree | 1e96c1e295486bd89923000db784a98e6ee451b3 | |
parent | 4379b85197456cb0d639c42df5704dd298efc839 (diff) | |
parent | 444647af82db691f47efeaa0bd58ee68ac48c201 (diff) | |
download | chef-sp/test-azure-devops-branch.tar.gz |
Merge branch 'master' into sp/test-azure-devops-branchsp/test-azure-devops-branch
Signed-off-by: <>
33 files changed, 704 insertions, 341 deletions
diff --git a/.expeditor/config.yml b/.expeditor/config.yml index 9074e29a7f..438ee3c1a6 100644 --- a/.expeditor/config.yml +++ b/.expeditor/config.yml @@ -19,7 +19,8 @@ docker_images: - chef habitat_packages: - - chef-client + - chef-client: + also_build_for_linux_kernel2: true github: # The file where the MAJOR.MINOR.PATCH version is kept. The version in this file diff --git a/.travis.yml b/.travis.yml index 0594a68eab..b918dfe7d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,31 +36,31 @@ matrix: include: - env: INTEGRATION_SPECS_24: 1 - rvm: 2.4.4 + rvm: 2.4.5 sudo: true script: sudo -E $(which bundle) exec rake spec:integration; bundler_args: --without ci docgen guard integration maintenance omnibus_package --frozen - env: INTEGRATION_SPECS_25: 1 - rvm: 2.5.1 + rvm: 2.5.3 sudo: true script: sudo -E $(which bundle) exec rake spec:integration; bundler_args: --without ci docgen guard integration maintenance omnibus_package --frozen - env: FUNCTIONAL_SPECS_24: 1 - rvm: 2.4.4 + rvm: 2.4.5 sudo: true script: sudo -E $(which bundle) exec rake spec:functional; bundler_args: --without ci docgen guard integration maintenance omnibus_package --frozen - env: FUNCTIONAL_SPECS_25: 1 - rvm: 2.5.1 + rvm: 2.5.3 sudo: true script: sudo -E $(which bundle) exec rake spec:functional; bundler_args: --without ci docgen guard integration maintenance omnibus_package --frozen - env: UNIT_SPECS_24: 1 - rvm: 2.4.4 + rvm: 2.4.5 sudo: true script: - sudo -E $(which bundle) exec rake spec:unit; @@ -68,7 +68,7 @@ matrix: bundler_args: --without ci docgen guard integration maintenance omnibus_package --frozen - env: UNIT_SPECS_25: 1 - rvm: 2.5.1 + rvm: 2.5.3 sudo: true script: - sudo -E $(which bundle) exec rake spec:unit; @@ -76,7 +76,7 @@ matrix: bundler_args: --without ci docgen guard integration maintenance omnibus_package --frozen - env: CHEFSTYLE: 1 - rvm: 2.5.1 + rvm: 2.5.3 script: bundle exec rake style # also remove integration / external tests bundler_args: --without ci docgen guard integration maintenance omnibus_package --frozen @@ -86,36 +86,36 @@ matrix: - env: TEST_GEM: sethvargo/chef-sugar script: bundle exec tasks/bin/run_external_test $TEST_GEM master rake - rvm: 2.5.1 + rvm: 2.5.3 - env: - PEDANT_OPTS=--skip-oc_id - TEST_GEM=chef/chef-zero - CHEF_FS=true script: bundle exec tasks/bin/run_external_test $TEST_GEM master rake pedant - rvm: 2.5.1 + rvm: 2.5.3 - env: TEST_GEM: chef/cheffish script: bundle exec tasks/bin/run_external_test $TEST_GEM master rake spec - rvm: 2.5.1 + rvm: 2.5.3 - env: TEST_GEM: chefspec/chefspec script: bundle exec tasks/bin/run_external_test $TEST_GEM master rake - rvm: 2.5.1 + rvm: 2.5.3 - env: TEST_GEM: poise/halite script: bundle exec tasks/bin/run_external_test $TEST_GEM master rake spec - rvm: 2.5.1 + rvm: 2.5.3 - env: TEST_GEM: chef/knife-windows script: bundle exec tasks/bin/run_external_test $TEST_GEM master rake unit_spec - rvm: 2.5.1 + rvm: 2.5.3 # disable this pending a Chef 14 compat version of poise # - env: # TEST_GEM: poise/poise # script: bundle exec tasks/bin/run_external_test $TEST_GEM master rake spec - # rvm: 2.5.1 + # rvm: 2.5.3 ### START TEST KITCHEN ONLY ### - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -132,7 +132,7 @@ matrix: env: - AMAZON=2 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -149,7 +149,7 @@ matrix: env: - AMAZON=201X - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -166,7 +166,7 @@ matrix: env: - UBUNTU=14.04 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -183,7 +183,7 @@ matrix: env: - UBUNTU=16.04 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -200,7 +200,7 @@ matrix: env: - UBUNTU=18.04 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -217,7 +217,7 @@ matrix: env: - DEBIAN=8 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -234,7 +234,7 @@ matrix: env: - DEBIAN=9 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -251,7 +251,7 @@ matrix: env: - CENTOS=6 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -268,7 +268,7 @@ matrix: env: - CENTOS=7 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -285,7 +285,7 @@ matrix: env: - FEDORA=latest - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -302,7 +302,7 @@ matrix: env: - OPENSUSELEAP=42 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.5.1 + - rvm: 2.5.3 sudo: required before_install: - gem update --system $(grep rubygems omnibus_overrides.rb | cut -d'"' -f2) @@ -323,7 +323,7 @@ matrix: - sudo cat /var/log/squid3/access.log # Use test-kitchen to launch a centos docker container to run the full rspec tests against. This catches # errors in travis, before PRs are merged, hopefully before they become errors in jenkins. - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -340,7 +340,7 @@ matrix: env: - RSPEC_CENTOS=7 - KITCHEN_YAML=kitchen.travis.yml - - rvm: 2.4.4 + - rvm: 2.5.3 services: docker sudo: required gemfile: kitchen-tests/Gemfile diff --git a/CHANGELOG.md b/CHANGELOG.md index 39626f6f39..986c5d860d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,41 @@ <!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ --> -<!-- latest_release 14.6.17 --> -## [v14.6.17](https://github.com/chef/chef/tree/v14.6.17) (2018-10-06) +<!-- latest_release 14.6.43 --> +## [v14.6.43](https://github.com/chef/chef/tree/v14.6.43) (2018-10-25) #### Merged Pull Requests -- Only include the Windows distro files on Windows [#7727](https://github.com/chef/chef/pull/7727) ([tas50](https://github.com/tas50)) +- Update chef-vault and serverspec to the latest [#7774](https://github.com/chef/chef/pull/7774) ([tas50](https://github.com/tas50)) <!-- latest_release --> <!-- release_rollup since=14.5.33 --> ### Changes since 14.5.33 release #### Merged Pull Requests +- Update chef-vault and serverspec to the latest [#7774](https://github.com/chef/chef/pull/7774) ([tas50](https://github.com/tas50)) <!-- 14.6.43 --> +- Update InSpec to 3.0 [#7773](https://github.com/chef/chef/pull/7773) ([tas50](https://github.com/tas50)) <!-- 14.6.42 --> +- Switch back to chefstyle from git and use the updated chef omnibus def [#7772](https://github.com/chef/chef/pull/7772) ([tas50](https://github.com/tas50)) <!-- 14.6.41 --> +- Use the Chefstyle gem instead of a git checkout [#7770](https://github.com/chef/chef/pull/7770) ([tas50](https://github.com/tas50)) <!-- 14.6.40 --> +- Fix registry key bug when sensitive is true [#7767](https://github.com/chef/chef/pull/7767) ([josh-barker](https://github.com/josh-barker)) <!-- 14.6.39 --> +- Don't ship contributing.md and VERSION file in the gem [#7769](https://github.com/chef/chef/pull/7769) ([tas50](https://github.com/tas50)) <!-- 14.6.38 --> +- Throw better error on invalid resources actions [#7729](https://github.com/chef/chef/pull/7729) ([tas50](https://github.com/tas50)) <!-- 14.6.37 --> +- [chef/chef]Fix duplicate logs [#7698](https://github.com/chef/chef/pull/7698) ([dheerajd-msys](https://github.com/dheerajd-msys)) <!-- 14.6.36 --> +- Update Ruby to 2.5.3 [#7766](https://github.com/chef/chef/pull/7766) ([tas50](https://github.com/tas50)) <!-- 14.6.35 --> +- Bump train-core to 1.5.4 [#7760](https://github.com/chef/chef/pull/7760) ([chef-ci](https://github.com/chef-ci)) <!-- 14.6.34 --> +- Bump mixlib-archive to 0.4.18 [#7759](https://github.com/chef/chef/pull/7759) ([chef-ci](https://github.com/chef-ci)) <!-- 14.6.33 --> +- Update omnibus to use ruby-cleanup definition [#7757](https://github.com/chef/chef/pull/7757) ([tas50](https://github.com/tas50)) <!-- 14.6.32 --> +- Add support for localized system account to windows_task resource [#7679](https://github.com/chef/chef/pull/7679) ([jugatsu](https://github.com/jugatsu)) <!-- 14.6.31 --> +- Run more Travis tests on Ruby 2.5.1 [#7755](https://github.com/chef/chef/pull/7755) ([tas50](https://github.com/tas50)) <!-- 14.6.30 --> +- File provider: fix sticky bits management / preservation [#7753](https://github.com/chef/chef/pull/7753) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 14.6.29 --> +- Node Attributes: Build ImmutableMash properly in deep_merge! [#7752](https://github.com/chef/chef/pull/7752) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 14.6.28 --> +- Update Nokogiri to 1.8.5 [#7750](https://github.com/chef/chef/pull/7750) ([tas50](https://github.com/tas50)) <!-- 14.6.27 --> +- Update omnibus deps [#7749](https://github.com/chef/chef/pull/7749) ([tas50](https://github.com/tas50)) <!-- 14.6.26 --> +- Bump inspec-core to 2.3.24 [#7748](https://github.com/chef/chef/pull/7748) ([chef-ci](https://github.com/chef-ci)) <!-- 14.6.25 --> +- Bump inspec-core to 2.3.23 [#7747](https://github.com/chef/chef/pull/7747) ([chef-ci](https://github.com/chef-ci)) <!-- 14.6.24 --> +- When a property regex fails don't call it an option [#7745](https://github.com/chef/chef/pull/7745) ([tas50](https://github.com/tas50)) <!-- 14.6.23 --> +- Bump win32-taskscheduler to 2.0 [#7743](https://github.com/chef/chef/pull/7743) ([btm](https://github.com/btm)) <!-- 14.6.22 --> +- Bump ohai to 14.6.2 [#7742](https://github.com/chef/chef/pull/7742) ([chef-ci](https://github.com/chef-ci)) <!-- 14.6.21 --> +- Bump win32-taskscheduler to 1.0.12 [#7740](https://github.com/chef/chef/pull/7740) ([chef-ci](https://github.com/chef-ci)) <!-- 14.6.20 --> +- Enable x86_64-linux-kernel2 habitat builds for chef-client [#7722](https://github.com/chef/chef/pull/7722) ([smacfarlane](https://github.com/smacfarlane)) <!-- 14.6.19 --> +- Add the timezone resource from the timezone_lwrp cookbook [#7736](https://github.com/chef/chef/pull/7736) ([tas50](https://github.com/tas50)) <!-- 14.6.18 --> - Only include the Windows distro files on Windows [#7727](https://github.com/chef/chef/pull/7727) ([tas50](https://github.com/tas50)) <!-- 14.6.17 --> - Cleanup the Test Kitchen setup in omnibus [#7726](https://github.com/chef/chef/pull/7726) ([tas50](https://github.com/tas50)) <!-- 14.6.16 --> - better docs for Chef::Knife::Bootstrap#validate_options! [#7719](https://github.com/chef/chef/pull/7719) ([bankair](https://github.com/bankair)) <!-- 14.6.15 --> @@ -13,7 +13,7 @@ gem "cheffish", "~> 14" group(:omnibus_package) do gem "appbundler" gem "rb-readline" - gem "inspec-core", "~> 2" + gem "inspec-core", "~> 3" gem "chef-vault" end @@ -52,7 +52,6 @@ group(:development, :test) do gem "webmock" # for testing new chefstyle rules - # gem 'chefstyle', github: 'chef/chefstyle' gem "chefstyle", git: "https://github.com/chef/chefstyle.git", branch: "master" end diff --git a/Gemfile.lock b/Gemfile.lock index da758eb840..cf52fb108c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,18 +1,18 @@ GIT remote: https://github.com/chef/chefstyle.git - revision: 4a885da4a201b55f2a5568bc0ea054860ccbf3c3 + revision: 5e596babac0e107170ce7c5cc706646bf609ab25 branch: master specs: - chefstyle (0.10.0) + chefstyle (0.11.0) rubocop (= 0.55.0) PATH remote: . specs: - chef (14.6.17) + chef (14.6.43) addressable bundler (>= 1.10) - chef-config (= 14.6.17) + chef-config (= 14.6.43) chef-zero (>= 13.0) diff-lcs (~> 1.2, >= 1.2.4) erubis (~> 2.7) @@ -40,10 +40,10 @@ PATH specinfra (~> 2.10) syslog-logger (~> 1.6) uuidtools (~> 2.1.5) - chef (14.6.17-universal-mingw32) + chef (14.6.43-universal-mingw32) addressable bundler (>= 1.10) - chef-config (= 14.6.17) + chef-config (= 14.6.43) chef-zero (>= 13.0) diff-lcs (~> 1.2, >= 1.2.4) erubis (~> 2.7) @@ -79,14 +79,14 @@ PATH win32-mutex (~> 0.4.2) win32-process (~> 0.8.2) win32-service (~> 1.0) - win32-taskscheduler (~> 1.0.0) + win32-taskscheduler (~> 2.0) windows-api (~> 0.4.4) wmi-lite (~> 1.0) PATH remote: chef-config specs: - chef-config (14.6.17) + chef-config (14.6.43) addressable fuzzyurl mixlib-config (>= 2.2.12, < 3.0) @@ -106,7 +106,7 @@ GEM debug_inspector (>= 0.0.1) builder (3.2.3) byebug (10.0.2) - chef-vault (3.4.2) + chef-vault (3.4.3) chef-zero (14.0.6) ffi-yajl (~> 2.2) hashie (>= 2.0, < 4.0) @@ -149,7 +149,7 @@ GEM highline (1.7.10) htmlentities (4.3.4) iniparse (1.4.4) - inspec-core (2.3.10) + inspec-core (3.0.12) addressable (~> 2.4) faraday (>= 0.9.0) hashie (~> 3.4) @@ -168,7 +168,7 @@ GEM sslshake (~> 1.2) thor (~> 0.20) tomlrb (~> 1.2) - train-core (~> 1.5) + train-core (~> 1.5, >= 1.5.4) ipaddress (0.8.3) iso8601 (0.11.0) json (2.1.0) @@ -176,7 +176,9 @@ GEM addressable (~> 2.3) libyajl2 (1.2.0) method_source (0.9.0) - mixlib-archive (0.4.16) + mixlib-archive (0.4.18) + mixlib-log + mixlib-archive (0.4.18-universal-mingw32) mixlib-log mixlib-authentication (2.1.1) mixlib-cli (1.7.0) @@ -203,9 +205,9 @@ GEM net-ssh-gateway (>= 1.2.0) net-telnet (0.1.1) netrc (0.11.0) - octokit (4.12.0) + octokit (4.13.0) sawyer (~> 0.8.0, >= 0.5.3) - ohai (14.5.4) + ohai (14.6.2) chef-config (>= 12.8, < 15) ffi (~> 1.9) ffi-yajl (~> 2.2) @@ -249,7 +251,7 @@ GEM rspec-mocks (~> 3.8.0) rspec-core (3.8.0) rspec-support (~> 3.8.0) - rspec-expectations (3.8.1) + rspec-expectations (3.8.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-its (1.2.0) @@ -290,7 +292,7 @@ GEM simplecov-html (~> 0.10.0) simplecov-html (0.10.2) slop (3.6.0) - specinfra (2.76.2) + specinfra (2.76.3) net-scp net-ssh (>= 2.7) net-telnet (= 0.1.1) @@ -301,7 +303,7 @@ GEM systemu (2.6.5) thor (0.20.0) tomlrb (1.2.7) - train-core (1.5.0) + train-core (1.5.4) json (>= 1.8, < 3.0) mixlib-shellout (~> 2.0) travis (1.8.9) @@ -340,7 +342,7 @@ GEM win32-service (1.0.1) ffi ffi-win32-extensions - win32-taskscheduler (1.0.10) + win32-taskscheduler (2.0.0) ffi structured_warnings windows-api (0.4.4) @@ -360,7 +362,7 @@ DEPENDENCIES chef-vault cheffish (~> 14) chefstyle! - inspec-core (~> 2) + inspec-core (~> 3) netrc octokit pry @@ -378,4 +380,4 @@ DEPENDENCIES yard BUNDLED WITH - 1.16.5 + 1.16.6 @@ -1 +1 @@ -14.6.17
\ No newline at end of file +14.6.43
\ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 259d9b9617..378574103f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,6 +13,17 @@ environment: clone_folder: c:\projects\chef clone_depth: 1 + +skip_commits: + # version bumps by Expeditor happen as a separate commit after the merge, we can skip + message: /Bump version to [0-9.]+ by Chef Expeditor/ + # if ONLY the files listed below are changed in a commit, skip + files: + - MAINTAINERS.md + - MAINTAINERS.toml + - CHANGELOG.md + - RELEASE_NOTES.md + skip_tags: true branches: only: diff --git a/chef-config/lib/chef-config/version.rb b/chef-config/lib/chef-config/version.rb index bb0e285341..c6154f2ba6 100644 --- a/chef-config/lib/chef-config/version.rb +++ b/chef-config/lib/chef-config/version.rb @@ -21,7 +21,7 @@ module ChefConfig CHEFCONFIG_ROOT = File.expand_path("../..", __FILE__) - VERSION = "14.6.17".freeze + VERSION = "14.6.43".freeze end # diff --git a/chef-universal-mingw32.gemspec b/chef-universal-mingw32.gemspec index 6de12265d2..3b17837dac 100644 --- a/chef-universal-mingw32.gemspec +++ b/chef-universal-mingw32.gemspec @@ -14,7 +14,7 @@ gemspec.add_dependency "win32-process", "~> 0.8.2" gemspec.add_dependency "win32-service", "~> 1.0" gemspec.add_dependency "windows-api", "~> 0.4.4" gemspec.add_dependency "wmi-lite", "~> 1.0" -gemspec.add_dependency "win32-taskscheduler", "~> 1.0.0" +gemspec.add_dependency "win32-taskscheduler", "~> 2.0" gemspec.extensions << "ext/win32-eventlog/Rakefile" gemspec.files += Dir.glob("{distro,ext}/**/*") diff --git a/chef.gemspec b/chef.gemspec index b9a80a0b4b..7a1d5dfc68 100644 --- a/chef.gemspec +++ b/chef.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = "chef" s.version = Chef::VERSION s.platform = Gem::Platform::RUBY - s.extra_rdoc_files = ["README.md", "CONTRIBUTING.md", "LICENSE" ] + s.extra_rdoc_files = ["README.md", "LICENSE" ] s.summary = "A systems integration framework, built to bring the benefits of configuration management to your entire infrastructure." s.description = s.summary s.license = "Apache-2.0" @@ -59,5 +59,5 @@ Gem::Specification.new do |s| s.executables = %w{ chef-client chef-solo knife chef-shell chef-apply chef-resource-inspector } s.require_paths = %w{ lib } - s.files = %w{Gemfile Rakefile LICENSE README.md VERSION} + Dir.glob("{lib,lib-backcompat,tasks,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) } + Dir.glob("*.gemspec") + s.files = %w{Gemfile Rakefile LICENSE README.md} + Dir.glob("{lib,tasks,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) } + Dir.glob("*.gemspec") end diff --git a/kitchen-tests/cookbooks/end_to_end/recipes/default.rb b/kitchen-tests/cookbooks/end_to_end/recipes/default.rb index 3985cefd5a..2779ed92fc 100644 --- a/kitchen-tests/cookbooks/end_to_end/recipes/default.rb +++ b/kitchen-tests/cookbooks/end_to_end/recipes/default.rb @@ -9,6 +9,8 @@ hostname "chef-travis-ci.chef.io" apt_update +timezone "UTC" + include_recipe "ubuntu" if platform?("ubuntu") if platform_family?("rhel", "fedora", "amazon") diff --git a/lib/chef/application.rb b/lib/chef/application.rb index 81637eabb8..a63d8218f4 100644 --- a/lib/chef/application.rb +++ b/lib/chef/application.rb @@ -205,7 +205,7 @@ class Chef # Based on config and whether or not STDOUT is a tty, should we setup a # secondary logger for stdout? def want_additional_logger? - Chef::Config.is_default?(:log_location) && Chef::Config[:log_location].tty? && !Chef::Config[:daemonize] + ( Chef::Config[:log_location].class != IO ) && STDOUT.tty? && !Chef::Config[:daemonize] end def configure_stdout_logger diff --git a/lib/chef/file_content_management/deploy/mv_unix.rb b/lib/chef/file_content_management/deploy/mv_unix.rb index cbc9b903a8..dbf58914d5 100644 --- a/lib/chef/file_content_management/deploy/mv_unix.rb +++ b/lib/chef/file_content_management/deploy/mv_unix.rb @@ -1,6 +1,6 @@ # # Author:: Lamont Granquist (<lamont@chef.io>) -# Copyright:: Copyright 2013-2016, Chef Software Inc. +# Copyright:: Copyright 2013-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,9 +44,6 @@ class Chef Chef::Log.trace("Applying mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} to #{src}") - # i own the inode, so should be able to at least chmod it - ::File.chmod(mode, src) - # we may be running as non-root in which case because we are doing an mv we cannot preserve # the file modes. after the mv we have a different inode and if we don't have rights to # chown/chgrp on the inode then we can't fix the ownership. @@ -67,6 +64,10 @@ class Chef Chef::Log.warn("Could not set gid = #{gid} on #{src}, file modes not preserved") end + # i own the inode, so should be able to at least chmod it + # NOTE: this must come last due to POSIX stripping sticky mode bits on chown/chgrp + ::File.chmod(mode, src) + Chef::Log.trace("Moving temporary file #{src} into place at #{dst}") FileUtils.mv(src, dst) end diff --git a/lib/chef/mixin/params_validate.rb b/lib/chef/mixin/params_validate.rb index f77adecd60..a71bec6958 100644 --- a/lib/chef/mixin/params_validate.rb +++ b/lib/chef/mixin/params_validate.rb @@ -174,7 +174,9 @@ class Chef to_be.each do |tb| return true if value == tb end - raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}.") + # Ruby will print :something as something, which confuses users so make sure to print them as symbols + # by inspecting the value instead of just printing it + raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} must be equal to one of: #{to_be.map { |v| v.inspect }.join(", ")}! You passed #{value.inspect}.") end end @@ -300,7 +302,7 @@ class Chef Array(regex).flatten.each do |r| return true if r.match(value.to_s) end - raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}") + raise Exceptions::ValidationFailed, _validation_message(key, "Property #{key}'s value #{value} does not match regular expression #{regex.inspect}") end end diff --git a/lib/chef/node/attribute.rb b/lib/chef/node/attribute.rb index 46683d9405..05b625dd02 100644 --- a/lib/chef/node/attribute.rb +++ b/lib/chef/node/attribute.rb @@ -403,11 +403,11 @@ class Chef end def combined_override(*path) - immutablize(merge_overrides(path)) + merge_overrides(path) end def combined_default(*path) - immutablize(merge_defaults(path)) + merge_defaults(path) end def normal_unless(*args) @@ -599,9 +599,9 @@ class Chef # In all other cases, replace merge_onto with merge_with else if merge_with.kind_of?(Hash) - Chef::Node::VividMash.new(merge_with) + Chef::Node::ImmutableMash.new(merge_with) elsif merge_with.kind_of?(Array) - Chef::Node::AttrArray.new(merge_with) + Chef::Node::ImmutableArray.new(merge_with) else merge_with end diff --git a/lib/chef/provider/registry_key.rb b/lib/chef/provider/registry_key.rb index 7c7b190b95..6b226cc991 100644 --- a/lib/chef/provider/registry_key.rb +++ b/lib/chef/provider/registry_key.rb @@ -126,16 +126,22 @@ class Chef value[:data] = value[:data].to_i end unless current_value[:type] == value[:type] && current_value[:data] == value[:data] - converge_by_value = value - converge_by_value[:data] = "*sensitive value suppressed*" if new_resource.sensitive + converge_by_value = if new_resource.sensitive + value.merge(data: "*sensitive value suppressed*") + else + value + end converge_by("set value #{converge_by_value}") do registry.set_value(new_resource.key, value) end end else - converge_by_value = value - converge_by_value[:data] = "*sensitive value suppressed*" if new_resource.sensitive + converge_by_value = if new_resource.sensitive + value.merge(data: "*sensitive value suppressed*") + else + value + end converge_by("set value #{converge_by_value}") do registry.set_value(new_resource.key, value) @@ -152,8 +158,11 @@ class Chef end new_resource.unscrubbed_values.each do |value| unless @name_hash.key?(value[:name].downcase) - converge_by_value = value - converge_by_value[:data] = "*sensitive value suppressed*" if new_resource.sensitive + converge_by_value = if new_resource.sensitive + value.merge(data: "*sensitive value suppressed*") + else + value + end converge_by("create value #{converge_by_value}") do registry.set_value(new_resource.key, value) diff --git a/lib/chef/provider/windows_task.rb b/lib/chef/provider/windows_task.rb index 98dd8795fa..d2ac9fdc59 100644 --- a/lib/chef/provider/windows_task.rb +++ b/lib/chef/provider/windows_task.rb @@ -570,7 +570,16 @@ class Chef def logon_type # Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383566(v=vs.85).aspx # if nothing is passed as logon_type the TASK_LOGON_SERVICE_ACCOUNT is getting set as default so using that for comparision. - new_resource.password.nil? ? TaskScheduler::TASK_LOGON_SERVICE_ACCOUNT : TaskScheduler::TASK_LOGON_PASSWORD + user_id = new_resource.user + if Chef::ReservedNames::Win32::Security::SID.service_account_user?(user_id) + TaskScheduler::TASK_LOGON_SERVICE_ACCOUNT + elsif Chef::ReservedNames::Win32::Security::SID.group_user?(user_id) + TaskScheduler::TASK_LOGON_GROUP + elsif !new_resource.password.to_s.empty? # password is present + TaskScheduler::TASK_LOGON_PASSWORD + else + TaskScheduler::TASK_LOGON_INTERACTIVE_TOKEN + end end # This method checks if task and command properties exist since those two are mandatory properties to create a schedules task. diff --git a/lib/chef/resource/timezone.rb b/lib/chef/resource/timezone.rb new file mode 100644 index 0000000000..8834e2404f --- /dev/null +++ b/lib/chef/resource/timezone.rb @@ -0,0 +1,91 @@ +# +# Author:: Kirill Kouznetsov <agon.smith@gmail.com> +# +# Copyright 2018, Kirill Kouznetsov. +# Copyright 2018, Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource" + +class Chef + class Resource + class Timezone < Chef::Resource + preview_resource true + resource_name :timezone + + description "Use the timezone resource to change the system timezone." + introduced "14.6" + + property :timezone, String, + description: "The timezone value to set.", + name_property: true + + action :set do + description "Set the timezone." + + package "tzdata" do + package_name platform_family?("suse") ? "timezone" : "tzdata" + end + + if node["init_package"] == "systemd" + # Modern Amazon, Fedora, CentOS, RHEL, Ubuntu & Debian + cmd_set_tz = "/usr/bin/timedatectl --no-ask-password set-timezone #{new_resource.timezone}" + + cmd_check_if_set = "/usr/bin/timedatectl status" + cmd_check_if_set += " | /usr/bin/awk '/Time.*zone/{print}'" + cmd_check_if_set += " | grep -q #{new_resource.timezone}" + + execute cmd_set_tz do + action :run + not_if cmd_check_if_set + end + elsif platform_family?("rhel", "amazon") + # Old version of RHEL & CentOS + file "/etc/sysconfig/clock" do + owner "root" + group "root" + mode "0644" + action :create + content %{ZONE="#{new_resource.timezone}"\nUTC="true"\n} + end + + execute "tzdata-update" do + command "/usr/sbin/tzdata-update" + action :nothing + only_if { ::File.executable?("/usr/sbin/tzdata-update") } + subscribes :run, "file[/etc/sysconfig/clock]", :immediately + end + + link "/etc/localtime" do + to "/usr/share/zoneinfo/#{new_resource.timezone}" + not_if { ::File.executable?("/usr/sbin/tzdata-update") } + end + elsif platform_family?("debian") + file "/etc/timezone" do + action :create + content "#{new_resource.timezone}\n" + end + + bash "dpkg-reconfigure tzdata" do + user "root" + code "/usr/sbin/dpkg-reconfigure -f noninteractive tzdata" + action :nothing + subscribes :run, "file[/etc/timezone]", :immediately + end + end + end + end + end +end diff --git a/lib/chef/resource/windows_task.rb b/lib/chef/resource/windows_task.rb index 0232fe3064..405846cb9e 100644 --- a/lib/chef/resource/windows_task.rb +++ b/lib/chef/resource/windows_task.rb @@ -17,318 +17,320 @@ # require "chef/resource" +require "chef/win32/security" if Chef::Platform.windows? class Chef class Resource class WindowsTask < Chef::Resource - resource_name :windows_task - provides(:windows_task) { true } + if Chef::Platform.windows? + resource_name :windows_task + provides(:windows_task) { true } - description "Use the windows_task resource to create, delete or run a Windows scheduled task. Requires Windows Server 2008 or later due to API usage." - introduced "13.0" + description "Use the windows_task resource to create, delete or run a Windows scheduled task. Requires Windows Server 2008 or later due to API usage." + introduced "13.0" - allowed_actions :create, :delete, :run, :end, :enable, :disable, :change - default_action :create + allowed_actions :create, :delete, :run, :end, :enable, :disable, :change + default_action :create - property :task_name, String, regex: [/\A[^\/\:\*\?\<\>\|]+\z/], - description: "The task name, such as 'Task Name' or '/Task Name'", - name_property: true + property :task_name, String, regex: [/\A[^\/\:\*\?\<\>\|]+\z/], + description: "The task name, such as 'Task Name' or '/Task Name'", + name_property: true - property :command, String, - description: "The command to be executed by the windows scheduled task." + property :command, String, + description: "The command to be executed by the windows scheduled task." - property :cwd, String, - description: "The directory the task will be run from." + property :cwd, String, + description: "The directory the task will be run from." - property :user, String, - description: "The user to run the task as.", - default: "SYSTEM" + property :user, String, + description: "The user to run the task as.", + default: Chef::ReservedNames::Win32::Security::SID.LocalSystem.account_simple_name - property :password, String, - description: "The user’s password. The user property must be set if using this property." + property :password, String, + description: "The user’s password. The user property must be set if using this property." - property :run_level, Symbol, equal_to: [:highest, :limited], - description: "Run with ':limited' or ':highest' privileges.", - default: :limited + property :run_level, Symbol, equal_to: [:highest, :limited], + description: "Run with ':limited' or ':highest' privileges.", + default: :limited - property :force, [TrueClass, FalseClass], - description: "When used with create, will update the task.", - default: false + property :force, [TrueClass, FalseClass], + description: "When used with create, will update the task.", + default: false - property :interactive_enabled, [TrueClass, FalseClass], - description: "Allow task to run interactively or non-interactively. Requires user and password to also be set.", - default: false + property :interactive_enabled, [TrueClass, FalseClass], + description: "Allow task to run interactively or non-interactively. Requires user and password to also be set.", + default: false - property :frequency_modifier, [Integer, String], - default: 1 + property :frequency_modifier, [Integer, String], + default: 1 - property :frequency, Symbol, equal_to: [:minute, - :hourly, - :daily, - :weekly, - :monthly, - :once, - :on_logon, - :onstart, - :on_idle, - :none], - description: "The frequency with which to run the task." + property :frequency, Symbol, equal_to: [:minute, + :hourly, + :daily, + :weekly, + :monthly, + :once, + :on_logon, + :onstart, + :on_idle, + :none], + description: "The frequency with which to run the task." - property :start_day, String, - description: "Specifies the first date on which the task runs in MM/DD/YYYY format." + property :start_day, String, + description: "Specifies the first date on which the task runs in MM/DD/YYYY format." - property :start_time, String, - description: "Specifies the start time to run the task, in HH:mm format." + property :start_time, String, + description: "Specifies the start time to run the task, in HH:mm format." - property :day, [String, Integer], - description: "The day(s) on which the task runs." + property :day, [String, Integer], + description: "The day(s) on which the task runs." - property :months, String, - description: "The Months of the year on which the task runs, such as: 'JAN, FEB' or '\*'. Multiple months should be comma delimited. e.g. 'Jan, Feb, Mar, Dec'." + property :months, String, + description: "The Months of the year on which the task runs, such as: 'JAN, FEB' or '\*'. Multiple months should be comma delimited. e.g. 'Jan, Feb, Mar, Dec'." - property :idle_time, Integer, - description: "For :on_idle frequency, the time (in minutes) without user activity that must pass to trigger the task, from 1 - 999." + property :idle_time, Integer, + description: "For :on_idle frequency, the time (in minutes) without user activity that must pass to trigger the task, from 1 - 999." - property :random_delay, [String, Integer], - description: "Delays the task up to a given time (in seconds)." + property :random_delay, [String, Integer], + description: "Delays the task up to a given time (in seconds)." - property :execution_time_limit, [String, Integer], - description: "The maximum time (in seconds) the task will run.", - default: "PT72H" # 72 hours in ISO8601 duration format + property :execution_time_limit, [String, Integer], + description: "The maximum time (in seconds) the task will run.", + default: "PT72H" # 72 hours in ISO8601 duration format - property :minutes_duration, [String, Integer], - description: "" + property :minutes_duration, [String, Integer], + description: "" - property :minutes_interval, [String, Integer], - description: "" + property :minutes_interval, [String, Integer], + description: "" - property :priority, Integer, - description: "Use to set Priority Levels range from 0 to 10.", - default: 7, callbacks: { "should be in range of 0 to 10" => proc { |v| v >= 0 && v <= 10 } } + property :priority, Integer, + description: "Use to set Priority Levels range from 0 to 10.", + default: 7, callbacks: { "should be in range of 0 to 10" => proc { |v| v >= 0 && v <= 10 } } - property :disallow_start_if_on_batteries, [TrueClass, FalseClass], - introduced: "14.4", default: false, - description: "Disallow start of the task if the system is running on battery power." + property :disallow_start_if_on_batteries, [TrueClass, FalseClass], + introduced: "14.4", default: false, + description: "Disallow start of the task if the system is running on battery power." - property :stop_if_going_on_batteries, [TrueClass, FalseClass], - introduced: "14.4", default: false, - description: "Scheduled task option when system is switching on battery." + property :stop_if_going_on_batteries, [TrueClass, FalseClass], + introduced: "14.4", default: false, + description: "Scheduled task option when system is switching on battery." - attr_accessor :exists, :task, :command_arguments + attr_accessor :exists, :task, :command_arguments - SYSTEM_USERS = ['NT AUTHORITY\SYSTEM', "SYSTEM", 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE', 'BUILTIN\USERS', "USERS"].freeze - VALID_WEEK_DAYS = %w{ mon tue wed thu fri sat sun * }.freeze - VALID_DAYS_OF_MONTH = ("1".."31").to_a << "last" << "lastday" - VALID_MONTHS = %w{JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC *}.freeze - VALID_WEEKS = %w{FIRST SECOND THIRD FOURTH LAST LASTDAY}.freeze + VALID_WEEK_DAYS = %w{ mon tue wed thu fri sat sun * }.freeze + VALID_DAYS_OF_MONTH = ("1".."31").to_a << "last" << "lastday" + VALID_MONTHS = %w{JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC *}.freeze + VALID_WEEKS = %w{FIRST SECOND THIRD FOURTH LAST LASTDAY}.freeze - def after_created - if random_delay - validate_random_delay(random_delay, frequency) - random_delay(sec_to_min(random_delay)) - end + def after_created + if random_delay + validate_random_delay(random_delay, frequency) + random_delay(sec_to_min(random_delay)) + end - if execution_time_limit - execution_time_limit(259200) if execution_time_limit == "PT72H" - raise ArgumentError, "Invalid value passed for `execution_time_limit`. Please pass seconds as an Integer (e.g. 60) or a String with numeric values only (e.g. '60')." unless numeric_value_in_string?(execution_time_limit) - execution_time_limit(sec_to_min(execution_time_limit)) - end + if execution_time_limit + execution_time_limit(259200) if execution_time_limit == "PT72H" + raise ArgumentError, "Invalid value passed for `execution_time_limit`. Please pass seconds as an Integer (e.g. 60) or a String with numeric values only (e.g. '60')." unless numeric_value_in_string?(execution_time_limit) + execution_time_limit(sec_to_min(execution_time_limit)) + end - validate_frequency(frequency) if action.include?(:create) || action.include?(:change) - validate_start_time(start_time, frequency) - validate_start_day(start_day, frequency) if start_day - validate_user_and_password(user, password) - validate_interactive_setting(interactive_enabled, password) - validate_create_frequency_modifier(frequency, frequency_modifier) if frequency_modifier - validate_create_day(day, frequency, frequency_modifier) if day - validate_create_months(months, frequency) if months - validate_frequency_monthly(frequency_modifier, months, day) if frequency == :monthly - validate_idle_time(idle_time, frequency) - idempotency_warning_for_frequency_weekly(day, start_day) if frequency == :weekly - end + validate_frequency(frequency) if action.include?(:create) || action.include?(:change) + validate_start_time(start_time, frequency) + validate_start_day(start_day, frequency) if start_day + validate_user_and_password(user, password) + validate_interactive_setting(interactive_enabled, password) + validate_create_frequency_modifier(frequency, frequency_modifier) if frequency_modifier + validate_create_day(day, frequency, frequency_modifier) if day + validate_create_months(months, frequency) if months + validate_frequency_monthly(frequency_modifier, months, day) if frequency == :monthly + validate_idle_time(idle_time, frequency) + idempotency_warning_for_frequency_weekly(day, start_day) if frequency == :weekly + end - private + private - ## Resource is not idempotent when day, start_day is not provided with frequency :weekly - ## we set start_day when not given by user as current date based on which we set the day property for current current date day is monday .. - ## we set the monday as the day so at next run when new_resource.day is nil and current_resource day is monday due to which udpate gets called - def idempotency_warning_for_frequency_weekly(day, start_day) - if start_day.nil? && day.nil? - logger.warn "To maintain idempotency for frequency :weekly provide start_day, start_time and day." + ## Resource is not idempotent when day, start_day is not provided with frequency :weekly + ## we set start_day when not given by user as current date based on which we set the day property for current current date day is monday .. + ## we set the monday as the day so at next run when new_resource.day is nil and current_resource day is monday due to which udpate gets called + def idempotency_warning_for_frequency_weekly(day, start_day) + if start_day.nil? && day.nil? + logger.warn "To maintain idempotency for frequency :weekly provide start_day, start_time and day." + end end - end - # Validate the passed value is numeric values only if it is a string - def numeric_value_in_string?(val) - return true if Integer(val) - rescue ArgumentError - false - end + # Validate the passed value is numeric values only if it is a string + def numeric_value_in_string?(val) + return true if Integer(val) + rescue ArgumentError + false + end - def validate_frequency(frequency) - if frequency.nil? || !([:minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle, :none].include?(frequency)) - raise ArgumentError, "Frequency needs to be provided. Valid frequencies are :minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle, :none." + def validate_frequency(frequency) + if frequency.nil? || !([:minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle, :none].include?(frequency)) + raise ArgumentError, "Frequency needs to be provided. Valid frequencies are :minute, :hourly, :daily, :weekly, :monthly, :once, :on_logon, :onstart, :on_idle, :none." + end end - end - def validate_frequency_monthly(frequency_modifier, months, day) - # validates the frequency :monthly and raises error if frequency_modifier is first, second, thrid etc and day is not provided - if (frequency_modifier != 1) && (frequency_modifier_includes_days_of_weeks?(frequency_modifier)) && !(day) - raise ArgumentError, "Please select day on which you want to run the task e.g. 'Mon, Tue'. Multiple values must be seprated by comma." + def validate_frequency_monthly(frequency_modifier, months, day) + # validates the frequency :monthly and raises error if frequency_modifier is first, second, thrid etc and day is not provided + if (frequency_modifier != 1) && (frequency_modifier_includes_days_of_weeks?(frequency_modifier)) && !(day) + raise ArgumentError, "Please select day on which you want to run the task e.g. 'Mon, Tue'. Multiple values must be seprated by comma." + end + + # frequency_modifer 2-12 is used to set every (n) months, so using :months propety with frequency_modifer is not valid since they both used to set months. + # Not checking value 1 here for frequecy_modifier since we are setting that as default value it won't break anything since preference is given to months property + if (frequency_modifier.to_i.between?(2, 12)) && !(months.nil?) + raise ArgumentError, "For frequency :monthly either use property months or frequency_modifier to set months." + end end - # frequency_modifer 2-12 is used to set every (n) months, so using :months propety with frequency_modifer is not valid since they both used to set months. - # Not checking value 1 here for frequecy_modifier since we are setting that as default value it won't break anything since preference is given to months property - if (frequency_modifier.to_i.between?(2, 12)) && !(months.nil?) - raise ArgumentError, "For frequency :monthly either use property months or frequency_modifier to set months." + # returns true if frequency_modifer has values First, second, third, fourth, last, lastday + def frequency_modifier_includes_days_of_weeks?(frequency_modifier) + frequency_modifier = frequency_modifier.to_s.split(",") + frequency_modifier.map! { |value| value.strip.upcase } + (frequency_modifier - VALID_WEEKS).empty? end - end - # returns true if frequency_modifer has values First, second, third, fourth, last, lastday - def frequency_modifier_includes_days_of_weeks?(frequency_modifier) - frequency_modifier = frequency_modifier.to_s.split(",") - frequency_modifier.map! { |value| value.strip.upcase } - (frequency_modifier - VALID_WEEKS).empty? - end + def validate_random_delay(random_delay, frequency) + if [:on_logon, :onstart, :on_idle, :none].include? frequency + raise ArgumentError, "`random_delay` property is supported only for frequency :once, :minute, :hourly, :daily, :weekly and :monthly" + end - def validate_random_delay(random_delay, frequency) - if [:on_logon, :onstart, :on_idle, :none].include? frequency - raise ArgumentError, "`random_delay` property is supported only for frequency :once, :minute, :hourly, :daily, :weekly and :monthly" + raise ArgumentError, "Invalid value passed for `random_delay`. Please pass seconds as an Integer (e.g. 60) or a String with numeric values only (e.g. '60')." unless numeric_value_in_string?(random_delay) end - raise ArgumentError, "Invalid value passed for `random_delay`. Please pass seconds as an Integer (e.g. 60) or a String with numeric values only (e.g. '60')." unless numeric_value_in_string?(random_delay) - end + # @todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~f + def validate_start_day(start_day, frequency) + if start_day && frequency == :none + raise ArgumentError, "`start_day` property is not supported with frequency: #{frequency}" + end - # @todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~f - def validate_start_day(start_day, frequency) - if start_day && frequency == :none - raise ArgumentError, "`start_day` property is not supported with frequency: #{frequency}" + # make sure the start_day is in MM/DD/YYYY format: http://rubular.com/r/cgjHemtWl5 + if start_day + raise ArgumentError, "`start_day` property must be in the MM/DD/YYYY format." unless /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d$/ =~ start_day + end end - # make sure the start_day is in MM/DD/YYYY format: http://rubular.com/r/cgjHemtWl5 - if start_day - raise ArgumentError, "`start_day` property must be in the MM/DD/YYYY format." unless /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d$/ =~ start_day + # @todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~ + def validate_start_time(start_time, frequency) + if start_time + raise ArgumentError, "`start_time` property is not supported with `frequency :none`" if frequency == :none + raise ArgumentError, "`start_time` property must be in the HH:mm format (e.g. 6:20pm -> 18:20)." unless /^[0-2][0-9]:[0-5][0-9]$/ =~ start_time + else + raise ArgumentError, "`start_time` needs to be provided with `frequency :once`" if frequency == :once + end end - end - # @todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~ - def validate_start_time(start_time, frequency) - if start_time - raise ArgumentError, "`start_time` property is not supported with `frequency :none`" if frequency == :none - raise ArgumentError, "`start_time` property must be in the HH:mm format (e.g. 6:20pm -> 18:20)." unless /^[0-2][0-9]:[0-5][0-9]$/ =~ start_time - else - raise ArgumentError, "`start_time` needs to be provided with `frequency :once`" if frequency == :once + def validate_user_and_password(user, password) + if password_required?(user) && password.nil? + raise ArgumentError, "Cannot specify a user other than the system users without specifying a password!. Valid passwordless users: '#{Chef::ReservedNames::Win32::Security::SID::SYSTEM_USER.join("', '")}'" + end end - end - def validate_user_and_password(user, password) - if password_required?(user) && password.nil? - raise ArgumentError, %q{Cannot specify a user other than the system users without specifying a password!. Valid passwordless users: 'NT AUTHORITY\SYSTEM', 'SYSTEM', 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE', 'BUILTIN\USERS', 'USERS'} + def password_required?(user) + return false if user.nil? + @password_required ||= !Chef::ReservedNames::Win32::Security::SID.system_user?(user) end - end - - def password_required?(user) - return false if user.nil? - @password_required ||= !SYSTEM_USERS.include?(user.upcase) - end - def validate_interactive_setting(interactive_enabled, password) - raise ArgumentError, "Please provide the password when attempting to set interactive/non-interactive." if interactive_enabled && password.nil? - end - - def validate_create_frequency_modifier(frequency, frequency_modifier) - if ([:on_logon, :onstart, :on_idle, :none].include?(frequency)) && ( frequency_modifier != 1) - raise ArgumentError, "frequency_modifier property not supported with frequency :#{frequency}" + def validate_interactive_setting(interactive_enabled, password) + raise ArgumentError, "Please provide the password when attempting to set interactive/non-interactive." if interactive_enabled && password.nil? end - if frequency == :monthly - unless (1..12).cover?(frequency_modifier.to_i) || frequency_modifier_includes_days_of_weeks?(frequency_modifier) - raise ArgumentError, "frequency_modifier value #{frequency_modifier} is invalid. Valid values for :monthly frequency are 1 - 12, 'FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST'." + def validate_create_frequency_modifier(frequency, frequency_modifier) + if ([:on_logon, :onstart, :on_idle, :none].include?(frequency)) && ( frequency_modifier != 1) + raise ArgumentError, "frequency_modifier property not supported with frequency :#{frequency}" end - else - unless frequency.nil? || frequency_modifier.nil? - frequency_modifier = frequency_modifier.to_i - min = 1 - max = case frequency - when :minute - 1439 - when :hourly - 23 - when :daily - 365 - when :weekly - 52 - else - min - end - unless frequency_modifier.between?(min, max) - raise ArgumentError, "frequency_modifier value #{frequency_modifier} is invalid. Valid values for :#{frequency} frequency are #{min} - #{max}." + + if frequency == :monthly + unless (1..12).cover?(frequency_modifier.to_i) || frequency_modifier_includes_days_of_weeks?(frequency_modifier) + raise ArgumentError, "frequency_modifier value #{frequency_modifier} is invalid. Valid values for :monthly frequency are 1 - 12, 'FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST'." + end + else + unless frequency.nil? || frequency_modifier.nil? + frequency_modifier = frequency_modifier.to_i + min = 1 + max = case frequency + when :minute + 1439 + when :hourly + 23 + when :daily + 365 + when :weekly + 52 + else + min + end + unless frequency_modifier.between?(min, max) + raise ArgumentError, "frequency_modifier value #{frequency_modifier} is invalid. Valid values for :#{frequency} frequency are #{min} - #{max}." + end end end end - end - - def validate_create_day(day, frequency, frequency_modifier) - raise ArgumentError, "day property is only valid for tasks that run monthly or weekly" unless [:weekly, :monthly].include?(frequency) - # This has been verified with schtask.exe https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks#d-dayday-- - # verified with earlier code if day "*" is given with frequency it raised exception Invalid value for /D option - raise ArgumentError, "day wild card (*) is only valid with frequency :weekly" if frequency == :monthly && day == "*" - - if day.is_a?(String) && day.to_i.to_s != day - days = day.split(",") - if days_includes_days_of_months?(days) - # Following error will be raise if day is set as 1-31 and frequency is selected as :weekly since those values are valid with only frequency :monthly - raise ArgumentError, "day values 1-31 or last is only valid with frequency :monthly" if frequency == :weekly - else - days.map! { |day| day.to_s.strip.downcase } - unless (days - VALID_WEEK_DAYS).empty? - raise ArgumentError, "day property invalid. Only valid values are: #{VALID_WEEK_DAYS.map(&:upcase).join(', ')}. Multiple values must be separated by a comma." + def validate_create_day(day, frequency, frequency_modifier) + raise ArgumentError, "day property is only valid for tasks that run monthly or weekly" unless [:weekly, :monthly].include?(frequency) + + # This has been verified with schtask.exe https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks#d-dayday-- + # verified with earlier code if day "*" is given with frequency it raised exception Invalid value for /D option + raise ArgumentError, "day wild card (*) is only valid with frequency :weekly" if frequency == :monthly && day == "*" + + if day.is_a?(String) && day.to_i.to_s != day + days = day.split(",") + if days_includes_days_of_months?(days) + # Following error will be raise if day is set as 1-31 and frequency is selected as :weekly since those values are valid with only frequency :monthly + raise ArgumentError, "day values 1-31 or last is only valid with frequency :monthly" if frequency == :weekly + else + days.map! { |day| day.to_s.strip.downcase } + unless (days - VALID_WEEK_DAYS).empty? + raise ArgumentError, "day property invalid. Only valid values are: #{VALID_WEEK_DAYS.map(&:upcase).join(', ')}. Multiple values must be separated by a comma." + end end end end - end - def validate_create_months(months, frequency) - raise ArgumentError, "months property is only valid for tasks that run monthly" if frequency != :monthly - if months.is_a?(String) - months = months.split(",") - months.map! { |month| month.strip.upcase } - unless (months - VALID_MONTHS).empty? - raise ArgumentError, "months property invalid. Only valid values are: #{VALID_MONTHS.join(', ')}. Multiple values must be separated by a comma." + def validate_create_months(months, frequency) + raise ArgumentError, "months property is only valid for tasks that run monthly" if frequency != :monthly + if months.is_a?(String) + months = months.split(",") + months.map! { |month| month.strip.upcase } + unless (months - VALID_MONTHS).empty? + raise ArgumentError, "months property invalid. Only valid values are: #{VALID_MONTHS.join(', ')}. Multiple values must be separated by a comma." + end end end - end - - # This method returns true if day has values from 1-31 which is a days of moths and used with frequency :monthly - def days_includes_days_of_months?(days) - days.map! { |day| day.to_s.strip.downcase } - (days - VALID_DAYS_OF_MONTH).empty? - end - def validate_idle_time(idle_time, frequency) - if !idle_time.nil? && frequency != :on_idle - raise ArgumentError, "idle_time property is only valid for tasks that run on_idle" + # This method returns true if day has values from 1-31 which is a days of moths and used with frequency :monthly + def days_includes_days_of_months?(days) + days.map! { |day| day.to_s.strip.downcase } + (days - VALID_DAYS_OF_MONTH).empty? end - if idle_time.nil? && frequency == :on_idle - raise ArgumentError, "idle_time value should be set for :on_idle frequency." - end - unless idle_time.nil? || idle_time > 0 && idle_time <= 999 - raise ArgumentError, "idle_time value #{idle_time} is invalid. Valid values for :on_idle frequency are 1 - 999." + + def validate_idle_time(idle_time, frequency) + if !idle_time.nil? && frequency != :on_idle + raise ArgumentError, "idle_time property is only valid for tasks that run on_idle" + end + if idle_time.nil? && frequency == :on_idle + raise ArgumentError, "idle_time value should be set for :on_idle frequency." + end + unless idle_time.nil? || idle_time > 0 && idle_time <= 999 + raise ArgumentError, "idle_time value #{idle_time} is invalid. Valid values for :on_idle frequency are 1 - 999." + end end - end - # Converts the number of seconds to an ISO8601 duration format and returns it. - # Ref : https://github.com/arnau/ISO8601/blob/master/lib/iso8601/duration.rb#L18-L23 - # e.g. - # ISO8601::Duration.new(65707200).to_s - # returns 'PT65707200S' - def sec_to_dur(seconds) - ISO8601::Duration.new(seconds.to_i).to_s - end + # Converts the number of seconds to an ISO8601 duration format and returns it. + # Ref : https://github.com/arnau/ISO8601/blob/master/lib/iso8601/duration.rb#L18-L23 + # e.g. + # ISO8601::Duration.new(65707200).to_s + # returns 'PT65707200S' + def sec_to_dur(seconds) + ISO8601::Duration.new(seconds.to_i).to_s + end - def sec_to_min(seconds) - seconds.to_i / 60 + def sec_to_min(seconds) + seconds.to_i / 60 + end end end end diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index d99aeed3ad..6324ce5b66 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -141,3 +141,4 @@ require "chef/resource/windows_printer_port" require "chef/resource/windows_shortcut" require "chef/resource/windows_task" require "chef/resource/windows_workgroup" +require "chef/resource/timezone" diff --git a/lib/chef/version.rb b/lib/chef/version.rb index 274f6323bc..4626d341e2 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -23,7 +23,7 @@ require "chef/version_string" class Chef CHEF_ROOT = File.expand_path("../..", __FILE__) - VERSION = Chef::VersionString.new("14.6.17") + VERSION = Chef::VersionString.new("14.6.43") end # diff --git a/lib/chef/win32/security/sid.rb b/lib/chef/win32/security/sid.rb index b551cbd2e3..43efc6e3fe 100644 --- a/lib/chef/win32/security/sid.rb +++ b/lib/chef/win32/security/sid.rb @@ -246,6 +246,45 @@ class Chef SID.from_account("#{::ENV['USERDOMAIN']}\\#{::ENV['USERNAME']}") end + SERVICE_ACCOUNT_USERS = [self.LocalSystem, + self.NtLocal, + self.NtNetwork].flat_map do |user_type| + [user_type.account_simple_name.upcase, + user_type.account_name.upcase] + end.freeze + + BUILT_IN_GROUPS = [self.BuiltinAdministrators, + self.BuiltinUsers, self.Guests].flat_map do |user_type| + [user_type.account_simple_name.upcase, + user_type.account_name.upcase] + end.freeze + + SYSTEM_USER = SERVICE_ACCOUNT_USERS + BUILT_IN_GROUPS + + # Сheck if the user belongs to service accounts category + # + # @return [Boolean] True or False + # + def self.service_account_user?(user) + SERVICE_ACCOUNT_USERS.include?(user.to_s.upcase) + end + + # Сheck if the user is in builtin system group + # + # @return [Boolean] True or False + # + def self.group_user?(user) + BUILT_IN_GROUPS.include?(user.to_s.upcase) + end + + # Сheck if the user belongs to system users category + # + # @return [Boolean] True or False + # + def self.system_user?(user) + SYSTEM_USER.include?(user.to_s.upcase) + end + # See https://technet.microsoft.com/en-us/library/cc961992.aspx # In practice, this is SID.Administrators if the current_user is an admin (even if not # running elevated), and is current_user otherwise. diff --git a/omnibus/Gemfile.lock b/omnibus/Gemfile.lock index 1359436f7a..36e0961c4e 100644 --- a/omnibus/Gemfile.lock +++ b/omnibus/Gemfile.lock @@ -1,10 +1,10 @@ GIT remote: https://github.com/chef/omnibus - revision: 386cd17f6a6365bd4585761a2738b4561fbaea97 + revision: 6cfec3a04de67aea335c23b5a3bd334a3a68fafe branch: master specs: - omnibus (6.0.1) - aws-sdk (~> 2) + omnibus (6.0.4) + aws-sdk-s3 (~> 1) chef-sugar (>= 3.3) cleanroom (~> 1.0) ffi-yajl (~> 2.2) @@ -18,7 +18,7 @@ GIT GIT remote: https://github.com/chef/omnibus-software - revision: 67a458d2e8a55b267fe0b47f6e1ec9c01e097137 + revision: 1d0fbaba922b31444c91f8e5a440ca3ac50aae67 branch: master specs: omnibus-software (4.0.0) @@ -31,13 +31,20 @@ GEM addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) awesome_print (1.8.0) - aws-sdk (2.11.144) - aws-sdk-resources (= 2.11.144) - aws-sdk-core (2.11.144) + aws-eventstream (1.0.1) + aws-partitions (1.106.0) + aws-sdk-core (3.35.0) + aws-eventstream (~> 1.0) + aws-partitions (~> 1.0) aws-sigv4 (~> 1.0) jmespath (~> 1.0) - aws-sdk-resources (2.11.144) - aws-sdk-core (= 2.11.144) + aws-sdk-kms (1.11.0) + aws-sdk-core (~> 3, >= 3.26.0) + aws-sigv4 (~> 1.0) + aws-sdk-s3 (1.23.0) + aws-sdk-core (~> 3, >= 3.26.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.0) aws-sigv4 (1.0.3) berkshelf (7.0.6) chef (>= 13.6.52) @@ -171,7 +178,7 @@ GEM ipaddress (0.8.3) iso8601 (0.11.0) jmespath (1.4.0) - kitchen-vagrant (1.3.4) + kitchen-vagrant (1.3.5) test-kitchen (~> 1.4) libyajl2 (1.2.0) license_scout (1.0.16) @@ -184,7 +191,9 @@ GEM multi_json (~> 1.10) method_source (0.9.0) minitar (0.6.1) - mixlib-archive (0.4.16) + mixlib-archive (0.4.18) + mixlib-log + mixlib-archive (0.4.18-universal-mingw32) mixlib-log mixlib-authentication (2.1.1) mixlib-cli (1.7.0) @@ -215,9 +224,9 @@ GEM net-ssh-gateway (>= 1.2.0) net-telnet (0.1.1) nori (2.6.0) - octokit (4.12.0) + octokit (4.13.0) sawyer (~> 0.8.0, >= 0.5.3) - ohai (14.5.4) + ohai (14.6.2) chef-config (>= 12.8, < 15) ffi (~> 1.9) ffi-yajl (~> 2.2) @@ -285,7 +294,7 @@ GEM solve (4.0.0) molinillo (~> 0.6) semverse (>= 1.1, < 3.0) - specinfra (2.76.2) + specinfra (2.76.3) net-scp net-ssh (>= 2.7) net-telnet (= 0.1.1) @@ -326,12 +335,12 @@ GEM win32-service (1.0.1) ffi ffi-win32-extensions - win32-taskscheduler (1.0.10) + win32-taskscheduler (1.0.12) ffi structured_warnings windows-api (0.4.4) win32-api (>= 1.4.5) - winrm (2.2.3) + winrm (2.3.0) builder (>= 2.1.2) erubis (~> 2.7) gssapi (~> 1.2) @@ -343,7 +352,7 @@ GEM winrm-elevated (1.1.0) winrm (~> 2.0) winrm-fs (~> 1.0) - winrm-fs (1.3.0) + winrm-fs (1.3.1) erubis (~> 2.7) logging (>= 1.6.1, < 3.0) rubyzip (~> 1.1) @@ -370,4 +379,4 @@ DEPENDENCIES winrm-fs (~> 1.0) BUNDLED WITH - 1.16.5 + 1.16.6 diff --git a/omnibus/config/projects/chef.rb b/omnibus/config/projects/chef.rb index 78301b59b5..4efaa57424 100644 --- a/omnibus/config/projects/chef.rb +++ b/omnibus/config/projects/chef.rb @@ -68,7 +68,7 @@ if windows? dependency "ruby-windows-devkit-bash" end -dependency "chef-cleanup" +dependency "ruby-cleanup" package :rpm do signing_passphrase ENV["OMNIBUS_RPM_SIGNING_PASSPHRASE"] diff --git a/omnibus_overrides.rb b/omnibus_overrides.rb index 5a2596d3ae..2499452a44 100644 --- a/omnibus_overrides.rb +++ b/omnibus_overrides.rb @@ -6,7 +6,7 @@ # software here: bundle exec rake dependencies:update_omnibus_gemfile_lock override :rubygems, version: "2.7.6" override :bundler, version: "1.16.1" -override "nokogiri", version: "1.8.2" +override "nokogiri", version: "1.8.5" override "libffi", version: "3.2.1" override "libiconv", version: "1.15" override "liblzma", version: "5.2.4" @@ -17,7 +17,7 @@ override "libyaml", version: "0.1.7" override "makedepend", version: "1.0.5" override "ncurses", version: "5.9" override "pkg-config-lite", version: "0.28-1" -override "ruby", version: "2.5.1" +override "ruby", version: "2.5.3" override "ruby-windows-devkit-bash", version: "3.1.23-4-msys-1.0.18" override "util-macros", version: "1.19.0" override "xproto", version: "7.0.28" diff --git a/spec/functional/resource/windows_task_spec.rb b/spec/functional/resource/windows_task_spec.rb index a2cd4b97d7..cb14da80d8 100644 --- a/spec/functional/resource/windows_task_spec.rb +++ b/spec/functional/resource/windows_task_spec.rb @@ -1571,7 +1571,7 @@ describe Chef::Resource::WindowsTask, :windows_only do it "raises error" do subject.user "Administrator" subject.frequency :onstart - expect { subject.after_created }.to raise_error(%q{Cannot specify a user other than the system users without specifying a password!. Valid passwordless users: 'NT AUTHORITY\SYSTEM', 'SYSTEM', 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE', 'BUILTIN\USERS', 'USERS'}) + expect { subject.after_created }.to raise_error(%q{Cannot specify a user other than the system users without specifying a password!. Valid passwordless users: 'SYSTEM', 'NT AUTHORITY\SYSTEM', 'LOCAL SERVICE', 'NT AUTHORITY\LOCAL SERVICE', 'NETWORK SERVICE', 'NT AUTHORITY\NETWORK SERVICE', 'ADMINISTRATORS', 'BUILTIN\ADMINISTRATORS', 'USERS', 'BUILTIN\USERS', 'GUESTS', 'BUILTIN\GUESTS'}) end end diff --git a/spec/unit/environment_spec.rb b/spec/unit/environment_spec.rb index a342d6d7cd..483ee615a2 100644 --- a/spec/unit/environment_spec.rb +++ b/spec/unit/environment_spec.rb @@ -317,7 +317,7 @@ describe Chef::Environment do it "validates the name given in the params" do expect(@environment.update_from_params(name: "@$%^&*()")).to be_falsey - expect(@environment.invalid_fields[:name]).to eq(%q{Option name's value @$%^&*() does not match regular expression /^[\-[:alnum:]_]+$/}) + expect(@environment.invalid_fields[:name]).to eq(%q{Property name's value @$%^&*() does not match regular expression /^[\-[:alnum:]_]+$/}) end it "updates the description from parameters[:description]" do diff --git a/spec/unit/file_content_management/deploy/mv_unix_spec.rb b/spec/unit/file_content_management/deploy/mv_unix_spec.rb index 6c8736ae38..a31074e4bd 100644 --- a/spec/unit/file_content_management/deploy/mv_unix_spec.rb +++ b/spec/unit/file_content_management/deploy/mv_unix_spec.rb @@ -1,6 +1,6 @@ # # Author:: Daniel DeLeo (<dan@chef.io>) -# Copyright:: Copyright 2013-2016, Chef Software Inc. +# Copyright:: Copyright 2013-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -98,4 +98,16 @@ describe Chef::FileContentManagement::Deploy::MvUnix do end end + + describe "when testing against real files", unix_only: true do + it "preserves sticky bits" do + staging_file = Tempfile.new("staging_file") + target_file = Tempfile.new("target_file") + File.chmod(04755, target_file.path) + content_deployer.deploy(staging_file.path, target_file.path) + expect(::File.stat(target_file.path).mode & 07777).to eql(04755) + staging_file.unlink + target_file.unlink + end + end end diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb index 0ca5f83adc..ff912ee7a6 100644 --- a/spec/unit/node_spec.rb +++ b/spec/unit/node_spec.rb @@ -1818,4 +1818,37 @@ describe Chef::Node do expect(node["a"]["key"]).to eql(1) end end + + describe "when abusing the deep merge cache" do + # https://github.com/chef/chef/issues/7738 + it "do not corrupt VividMashes that are part of the merge set and not the merge_onto set" do + # need to have a merge two-deep (not at the top-level) between at least two default (or two override) + # levels where the lowest priority one is the one that is going to be corrupted + node.default["foo"]["bar"]["baz"] = "fizz" + node.env_default["foo"]["bar"]["quux"] = "buzz" + node.default["foo"]["bar"].tap do |bar| + bar["test"] = "wrong" + # this triggers a deep merge + node["foo"]["bar"]["test"] + # this should correctly write and dirty the cache so the next read does another deep merge on the correct __root__ + bar["test"] = "right" + end + expect(node["foo"]["bar"]["test"]).to eql("right") + end + + it "do not corrupt VividMashes that are part of the merge set and not the merge_onto set (when priorities are reversed)" do + # need to have a merge two-deep (not at the top-level) between at least two default (or two override) + # levels where the *HIGHEST* priority one is the one that is going to be corrupted + node.env_default["foo"]["bar"]["baz"] = "fizz" + node.default["foo"]["bar"]["quux"] = "buzz" + node.env_default["foo"]["bar"].tap do |bar| + bar["test"] = "wrong" + # this triggers a deep merge + node["foo"]["bar"]["test"] + # this should correctly write and dirty the cache so the next read does another deep merge on the correct __root__ + bar["test"] = "right" + end + expect(node["foo"]["bar"]["test"]).to eql("right") + end + end end diff --git a/spec/unit/provider/registry_key_spec.rb b/spec/unit/provider/registry_key_spec.rb index 3563af4dc4..9a7dd9996e 100644 --- a/spec/unit/provider/registry_key_spec.rb +++ b/spec/unit/provider/registry_key_spec.rb @@ -309,6 +309,80 @@ describe Chef::Provider::RegistryKey do @provider.action_create end end + + context "when sensitive is true" do + before(:each) do + @new_resource.sensitive(true) + end + + context "and key exists" do + let(:keyname) { 'hklm\\software\\opscode\\testing\\sensitive\exists' } + before(:each) do + expect(@double_registry).to receive(:key_exists?).twice.with(keyname).and_return(true) + expect(@double_registry).to receive(:get_values).with(keyname).and_return( + [ + { name: "one", type: :string, data: "initial value" }, + { name: "two", type: :dword, data: 9001 } + ] + ) + end + + context "and type is a string" do + let(:testval1) { { name: "one", type: :string, data: "first_value" } } + + it "sets the unscrubbed value" do + expect(@double_registry).to receive(:set_value).with(keyname, testval1) + @provider.load_current_resource + @provider.action_create + end + end + + context "and type is a dword" do + let(:testval1) { { name: "two", type: :dword, data: 12345 } } + + it "sets the unscrubbed value" do + expect(@double_registry).to receive(:set_value).with(keyname, testval1) + @provider.load_current_resource + @provider.action_create + end + end + end + + context "and key does not exist" do + let(:keyname) { 'hklm\\software\\opscode\\testing\\sensitive\missing' } + let(:testval1) { { name: "one", type: :string, data: "first_value" } } + + before(:each) do + expect(@double_registry).to receive(:key_exists?).twice.with(keyname).and_return(false) + expect(@double_registry).to receive(:create_key).with(keyname, false) + end + + it "sets the unscrubbed value" do + expect(@double_registry).to receive(:set_value).with(keyname, testval1) + @provider.load_current_resource + @provider.action_create + end + end + end + end + + describe "action_create_if_missing" do + context "when sensitive is true" do + let(:keyname) { 'hklm\\software\\opscode\\testing\\create_if_missing\\sensitive' } + let(:testval1) { { name: "one", type: :string, data: "first_value" } } + + before(:each) do + expect(@double_registry).to receive(:key_exists?).twice.with(keyname).and_return(true) + expect(@double_registry).to receive(:get_values).with(keyname).and_return([]) + @new_resource.sensitive(true) + end + + it "sets the unscrubbed value" do + expect(@double_registry).to receive(:set_value).with(keyname, testval1) + @provider.load_current_resource + @provider.action_create_if_missing + end + end end end diff --git a/spec/unit/provider/windows_task_spec.rb b/spec/unit/provider/windows_task_spec.rb index 3a046ab5de..3565da1ca3 100644 --- a/spec/unit/provider/windows_task_spec.rb +++ b/spec/unit/provider/windows_task_spec.rb @@ -416,6 +416,7 @@ describe Chef::Provider::WindowsTask, :windows_only do end it "return logon_type bindary value as 1 as if password is not nil" do + new_resource.user = "Administrator" new_resource.password = "abc" expect(provider.send(:logon_type)).to be(1) end diff --git a/spec/unit/resource/timezone.rb b/spec/unit/resource/timezone.rb new file mode 100644 index 0000000000..d91a5dd49b --- /dev/null +++ b/spec/unit/resource/timezone.rb @@ -0,0 +1,39 @@ +# +# Copyright:: Copyright 2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::Timezone do + let(:resource) { Chef::Resource::Timezone.new("fakey_fakerton") } + + it "sets resource name as :timezone" do + expect(resource.resource_name).to eql(:timezone) + end + + it "the timezone property is the name_property" do + expect(resource.timezone).to eql("fakey_fakerton") + end + + it "sets the default action as :set" do + expect(resource.action).to eql([:set]) + end + + it "supports the :set action only" do + expect { resource.action :set }.not_to raise_error + expect { resource.action :unset }.to raise_error + end +end diff --git a/spec/unit/resource/windows_task_spec.rb b/spec/unit/resource/windows_task_spec.rb index 76e2a86ee8..efbc1b1846 100644 --- a/spec/unit/resource/windows_task_spec.rb +++ b/spec/unit/resource/windows_task_spec.rb @@ -73,7 +73,7 @@ describe Chef::Resource::WindowsTask, :windows_only do end it "raises an error if the user is a non-system user" do resource.user "bob" - expect { resource.after_created }.to raise_error(ArgumentError, %q{Cannot specify a user other than the system users without specifying a password!. Valid passwordless users: 'NT AUTHORITY\SYSTEM', 'SYSTEM', 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE', 'BUILTIN\USERS', 'USERS'}) + expect { resource.after_created }.to raise_error(ArgumentError, %q{Cannot specify a user other than the system users without specifying a password!. Valid passwordless users: 'SYSTEM', 'NT AUTHORITY\SYSTEM', 'LOCAL SERVICE', 'NT AUTHORITY\LOCAL SERVICE', 'NETWORK SERVICE', 'NT AUTHORITY\NETWORK SERVICE', 'ADMINISTRATORS', 'BUILTIN\ADMINISTRATORS', 'USERS', 'BUILTIN\USERS', 'GUESTS', 'BUILTIN\GUESTS'}) end it "does not raise an error if the user is a system user" do |