diff options
author | John McCrae <john.mccrae@progress.com> | 2022-10-05 00:57:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-05 00:57:05 -0700 |
commit | 48303bc3820542f4dbfc6c4f0f3a8b5f151daed5 (patch) | |
tree | ea1742ac4c6e621d5ac87b9b61c28da11bec3aa1 | |
parent | 103720783c46a9932afe3d33b298c443d0006755 (diff) | |
parent | 9c43a97b4f2722f5e88ceb290817e82c4ef336b4 (diff) | |
download | chef-48303bc3820542f4dbfc6c4f0f3a8b5f151daed5.tar.gz |
Merge branch 'main' into fix-windows-powershell-package-bug
139 files changed, 2833 insertions, 515 deletions
diff --git a/.expeditor/adhoc-canary.omnibus.yml b/.expeditor/adhoc-canary.omnibus.yml index 1defa609d4..731a7fecdf 100644 --- a/.expeditor/adhoc-canary.omnibus.yml +++ b/.expeditor/adhoc-canary.omnibus.yml @@ -8,10 +8,17 @@ fips-platforms: - el-*-ppc64* - ubuntu-*-x86_64 - windows-* +skip-artifactory-platforms: + - freebsd-13-amd64 +windows-64-msystem: UCRT64 builder-to-testers-map: # aix-7.1-powerpc: # - aix-7.1-powerpc # - aix-7.2-powerpc + amazon-2022-aarch64: + - amazon-2022-aarch64 + amazon-2022-x86_64: + - amazon-2022-x86_64 debian-9-x86_64: - debian-9-x86_64 - debian-10-x86_64 @@ -38,9 +45,13 @@ builder-to-testers-map: - el-8-aarch64 el-8-x86_64: - el-8-x86_64 - freebsd-11-amd64: - - freebsd-11-amd64 + el-9-aarch64: + - el-9-aarch64 + el-9-x86_64: + - el-9-x86_64 + freebsd-12-amd64: - freebsd-12-amd64 + - freebsd-13-amd64 mac_os_x-10.15-x86_64: - mac_os_x-10.15-x86_64 - mac_os_x-11-x86_64 @@ -63,18 +74,17 @@ builder-to-testers-map: ubuntu-18.04-aarch64: - ubuntu-18.04-aarch64 - ubuntu-20.04-aarch64 + - ubuntu-22.04-aarch64 ubuntu-16.04-x86_64: - ubuntu-16.04-x86_64 - ubuntu-18.04-x86_64 - ubuntu-20.04-x86_64 - windows-2012r2-i386: - - windows-2012r2-i386 + - ubuntu-22.04-x86_64 windows-2012r2-x86_64: - windows-2012-x86_64 - windows-2012r2-x86_64 - windows-2016-x86_64 - windows-2019-x86_64 - windows-2022-x86_64 - - windows-8-x86_64 - windows-10-x86_64 - windows-11-x86_64 diff --git a/.expeditor/config.yml b/.expeditor/config.yml index a3d9c202d1..d1466484ff 100644 --- a/.expeditor/config.yml +++ b/.expeditor/config.yml @@ -17,9 +17,24 @@ rubygems: - chef-bin - chef-utils +# At the given time, trigger the following scheduled workloads +# https://expeditor.chef.io/docs/getting-started/subscriptions/#scheduling-workloads +schedules: + - name: nightly_build_main + description: "Run a nightly build in the Buildkite pipeline" + cronline: "0 6 * * *" + - name: nightly_build_chef_17 + description: "Run a nightly build in the Buildkite pipeline" + cronline: "30 9 * * 2,4" + - name: nightly_build_chef_16 + description: "Run a nightly build in the Buildkite pipeline" + cronline: "30 2 * * 2" + pipelines: - verify: public: true + env: + - IGNORE_ARTIFACTORY_RUBY_PROXY: true # Artifactory is throwing 500's when downloading some gems. - docker/build: definition: .expeditor/docker-build.pipeline.yml trigger: default @@ -30,17 +45,23 @@ pipelines: - omnibus/release: env: - IGNORE_CACHE: true # caching causes constant build failures + - IGNORE_ARTIFACTORY_RUBY_PROXY: true - omnibus/adhoc: definition: .expeditor/release.omnibus.yml env: - ADHOC: true - IGNORE_CACHE: true # caching causes constant build failures + - IGNORE_ARTIFACTORY_RUBY_PROXY: true # the adhoc-canary pipeline is used to test new omnibus workers - omnibus/adhoc-canary: canary: true definition: .expeditor/adhoc-canary.omnibus.yml env: - ADHOC: true + - IGNORE_ARTIFACTORY_RUBY_PROXY: true + - macos_universal_package: + description: Builds universal macos package using arch specific packages + definition: .expeditor/macos_universal_package.pipeline.yml github: # This deletes the GitHub PR branch after successfully merged into the release branch @@ -73,6 +94,7 @@ subscriptions: - workload: artifact_published:unstable:chef:{{version_constraint}} actions: - trigger_pipeline:docker/build + - trigger_pipeline:macos_universal_package - workload: artifact_published:current:chef:{{version_constraint}} actions: - bash:.expeditor/promote-docker-images.sh @@ -258,3 +280,12 @@ subscriptions: - workload: ruby_gem_published:train-winrm-* actions: - bash:.expeditor/update_dep.sh + - workload: schedule_triggered:chef/chef:main:nightly_build_main:* + actions: + - trigger_pipeline:omnibus/adhoc + - workload: schedule_triggered:chef/chef:chef-17:nightly_build_chef_17:* + actions: + - trigger_pipeline:omnibus/adhoc + - workload: schedule_triggered:chef/chef:chef-16:nightly_build_chef_16:* + actions: + - trigger_pipeline:omnibus/adhoc diff --git a/.expeditor/macos_universal_package.pipeline.yml b/.expeditor/macos_universal_package.pipeline.yml new file mode 100644 index 0000000000..6fddb90a89 --- /dev/null +++ b/.expeditor/macos_universal_package.pipeline.yml @@ -0,0 +1 @@ +# This pipeline is currently under development. diff --git a/.expeditor/release.omnibus.yml b/.expeditor/release.omnibus.yml index c8005ab292..5007f6567e 100644 --- a/.expeditor/release.omnibus.yml +++ b/.expeditor/release.omnibus.yml @@ -8,12 +8,18 @@ fips-platforms: - el-*-ppc64* - ubuntu-*-x86_64 - windows-* +skip-artifactory-platforms: + - freebsd-13-amd64 +windows-64-msystem: UCRT64 builder-to-testers-map: aix-7.1-powerpc: - aix-7.1-powerpc - aix-7.2-powerpc - amazon-2022-x86_64: - - amazon-2022-x86_64 + # - aix-7.3-powerpc + # amazon-2022-aarch64: + # - amazon-2022-aarch64 + # amazon-2022-x86_64: + # - amazon-2022-x86_64 debian-9-x86_64: - debian-9-x86_64 - debian-10-x86_64 @@ -40,9 +46,13 @@ builder-to-testers-map: - el-8-aarch64 el-8-x86_64: - el-8-x86_64 - freebsd-11-amd64: - - freebsd-11-amd64 + el-9-aarch64: + - el-9-aarch64 + el-9-x86_64: + - el-9-x86_64 + freebsd-12-amd64: - freebsd-12-amd64 + - freebsd-13-amd64 mac_os_x-10.15-x86_64: - mac_os_x-10.15-x86_64 - mac_os_x-11-x86_64 @@ -58,25 +68,25 @@ builder-to-testers-map: - sles-15-x86_64 sles-15-aarch64: - sles-15-aarch64 - solaris2-5.11-i386: - - solaris2-5.11-i386 - solaris2-5.11-sparc: - - solaris2-5.11-sparc + # solaris2-5.11-i386: + # - solaris2-5.11-i386 + # solaris2-5.11-sparc: + # - solaris2-5.11-sparc ubuntu-18.04-aarch64: - ubuntu-18.04-aarch64 - ubuntu-20.04-aarch64 + - ubuntu-22.04-aarch64 ubuntu-16.04-x86_64: - ubuntu-16.04-x86_64 - ubuntu-18.04-x86_64 - ubuntu-20.04-x86_64 - windows-2012r2-i386: - - windows-2012r2-i386 + - ubuntu-22.04-x86_64 windows-2012r2-x86_64: - - windows-2012-x86_64 + # - windows-2012-x86_64 - windows-2012r2-x86_64 - windows-2016-x86_64 - windows-2019-x86_64 - windows-2022-x86_64 - - windows-8-x86_64 - windows-10-x86_64 - windows-11-x86_64 + diff --git a/.expeditor/scripts/bk_win_functional.ps1 b/.expeditor/scripts/bk_win_functional.ps1 index 8b4a445b44..7d23d07b8f 100644 --- a/.expeditor/scripts/bk_win_functional.ps1 +++ b/.expeditor/scripts/bk_win_functional.ps1 @@ -7,11 +7,11 @@ Remove-Item -Path C:\ProgramData\chocolatey\bin\choco.exe -ErrorAction SilentlyC $ErrorActionPreference = 'Stop' -Write-Output "--- Enable Ruby 2.7" +Write-Output "--- Enable Ruby 3.1" -Write-Output "Register Installed Ruby Version 2.7 With Uru" -Start-Process "uru_rt.exe" -ArgumentList 'admin add C:\ruby27\bin' -Wait -uru 271 +Write-Output "Register Installed Ruby Version 3.1 With Uru" +Start-Process "uru_rt.exe" -ArgumentList 'admin add C:\ruby31\bin' -Wait +uru 312 if (-not $?) { throw "Can't Activate Ruby. Did Uru Registration Succeed?" } ruby -v if (-not $?) { throw "Can't run Ruby. Is it installed?" } diff --git a/.expeditor/scripts/ensure-minimum-viable-hab.ps1 b/.expeditor/scripts/ensure-minimum-viable-hab.ps1 index 10bfeb0fa8..716de60cf8 100644 --- a/.expeditor/scripts/ensure-minimum-viable-hab.ps1 +++ b/.expeditor/scripts/ensure-minimum-viable-hab.ps1 @@ -1,7 +1,8 @@ [Version]$hab_version = (hab --version).split(" ")[1].split("/")[0] if ($hab_version -lt [Version]"0.85.0" ) { Write-Host "--- :habicat: Installing the version of Habitat required" - install-habitat --version 0.85.0.20190916 + Set-ExecutionPolicy Bypass -Scope Process -Force + Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/habitat-sh/habitat/main/components/hab/install.ps1')) if (-not $?) { throw "Hab version is older than 0.85 and could not update it." } } else { Write-Host "--- :habicat: :thumbsup: Minimum required version of Habitat already installed" diff --git a/.expeditor/scripts/verify-plan.ps1 b/.expeditor/scripts/verify-plan.ps1 index 614d472964..6fbef95442 100644 --- a/.expeditor/scripts/verify-plan.ps1 +++ b/.expeditor/scripts/verify-plan.ps1 @@ -14,6 +14,16 @@ Write-Host "--- :8ball: :windows: Verifying $Plan" powershell -File "./.expeditor/scripts/ensure-minimum-viable-hab.ps1" if (-not $?) { throw "Could not ensure the minimum hab version required is installed." } +$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") + +Write-Host "--- :construction: Verifying Git is Installed" +$source = Get-Command -Name Git -Verbose +Write-Host "Which version of Git is installed? - " $source.version +if (-not ($source.name -match "git.exe")) { + choco install git -y + # gotta refresh the path so you can actually use Git now + $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") +} Write-Host "--- :key: Generating fake origin key" hab origin key generate $env:HAB_ORIGIN diff --git a/.expeditor/update_version.sh b/.expeditor/update_version.sh index 95840cadfc..18599cc18a 100755 --- a/.expeditor/update_version.sh +++ b/.expeditor/update_version.sh @@ -12,15 +12,23 @@ set -evx VERSION=$(cat VERSION) +ORIGINAL_VERSION=$(git show main:VERSION) sed -i -r "s/^(\s*)VERSION = \".+\"/\1VERSION = \"${VERSION}\"/" chef-config/lib/chef-config/version.rb sed -i -r "s/^(\s*)VERSION = \".+\"/\1VERSION = \"${VERSION}\"/" chef-bin/lib/chef-bin/version.rb sed -i -r "s/^(\s*)VERSION = \".+\"/\1VERSION = \"${VERSION}\"/" chef-utils/lib/chef-utils/version.rb sed -i -r "s/^(\s*)VERSION = \".+\"/\1VERSION = \"${VERSION}\"/" knife/lib/chef/knife/version.rb sed -i -r "s/VersionString\.new\(\".+\"\)/VersionString.new(\"${VERSION}\")/" lib/chef/version.rb +asdf global ruby "3.1.0" # Update the version inside Gemfile.lock -bundle update chef chef-config chef-utils --jobs=7 --conservative +sed -i -r "s/(^\s+chef\s+.+)${ORIGINAL_VERSION}(.+)/\1${VERSION}\2/" Gemfile.lock +sed -i -r "s/(^\s+chef-bin\s+.+)${ORIGINAL_VERSION}(.+)/\1${VERSION}\2/" Gemfile.lock +sed -i -r "s/(^\s+chef-config\s+.+)${ORIGINAL_VERSION}(.+)/\1${VERSION}\2/" Gemfile.lock +sed -i -r "s/(^\s+chef-utils\s+.+)${ORIGINAL_VERSION}(.+)/\1${VERSION}\2/" Gemfile.lock + +#Update the version in knife/Gemfile.lock +sed -i -r "s/(^\s+chef\s+.+)${ORIGINAL_VERSION}(.+)/\1${VERSION}\2/" knife/Gemfile.lock # Once Expeditor finishes executing this script, it will commit the changes and push # the commit as a new tag corresponding to the value in the VERSION file. diff --git a/.expeditor/verify.pipeline.yml b/.expeditor/verify.pipeline.yml index 14b168661f..e8833be063 100644 --- a/.expeditor/verify.pipeline.yml +++ b/.expeditor/verify.pipeline.yml @@ -7,41 +7,11 @@ expeditor: retry: automatic: limit: 1 - timeout_in_minutes: 45 + timeout_in_minutes: 60 steps: ######################################################################### - # Tests Ruby 2.6 -######################################################################### - -- label: "chef-utils Unit :ruby: 2.6" - commands: - - /workdir/.expeditor/scripts/bk_container_prep.sh - - cd chef-utils - - bundle config set --local without omnibus_package - - bundle config set --local path 'vendor/bundle' - - bundle install --jobs=3 --retry=3 - - bundle exec rake spec - expeditor: - executor: - docker: - image: rubydistros/ubuntu-18.04:2.6 - -- label: "chef-config Unit :ruby: 2.6" - commands: - - /workdir/.expeditor/scripts/bk_container_prep.sh - - cd chef-config - - bundle config set --local without omnibus_package - - bundle config set --local path 'vendor/bundle' - - bundle install --jobs=3 --retry=3 - - bundle exec rake spec - expeditor: - executor: - docker: - image: rubydistros/ubuntu-18.04:2.6 - -######################################################################### # Tests Ruby 3.1 ######################################################################### @@ -264,7 +234,7 @@ steps: docker: image: rubydistros/almalinux-8:3.1 -- label: "Functional Windows :ruby: 2.7" +- label: "Functional Windows :ruby: 3.1" commands: - .expeditor/scripts/bk_win_functional.ps1 expeditor: @@ -274,27 +244,27 @@ steps: single-use: true shell: ["powershell", "-Command"] -- label: "Integration Windows :ruby: 3.0" +- label: "Integration Windows :ruby: 3.1" commands: - /workdir/.expeditor/scripts/bk_win_integration.ps1 expeditor: executor: docker: host_os: windows - image: rubydistros/windows-2019:3.0 + image: rubydistros/windows-2019:3.1 environment: - FORCE_FFI_YAJL=ext - CHEF_LICENSE=accept-no-persist shell: ["powershell", "-Command"] -- label: "Unit Windows :ruby: 3.0" +- label: "Unit Windows :ruby: 3.1" commands: - /workdir/.expeditor/scripts/bk_win_unit.ps1 expeditor: executor: docker: host_os: windows - image: rubydistros/windows-2019:3.0 + image: rubydistros/windows-2019:3.1 environment: - FORCE_FFI_YAJL=ext - CHEF_LICENSE=accept-no-persist @@ -393,7 +363,7 @@ steps: - label: ":habicat: Windows plan" commands: - ./.expeditor/scripts/verify-plan.ps1 - timeout_in_minutes: 60 + timeout_in_minutes: 0 expeditor: executor: windows: diff --git a/.github/workflows/func_spec.yml b/.github/workflows/func_spec.yml index 2247b414fd..3900bd1d00 100644 --- a/.github/workflows/func_spec.yml +++ b/.github/workflows/func_spec.yml @@ -14,27 +14,30 @@ jobs: matrix: os: [windows-2019, windows-2022] # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0' - ruby: [2.7, '3.0'] + ruby: ['3.1'] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - bundler-cache: true - - run: bundle exec rspec spec/functional/resource/chocolatey_package_spec.rb + bundler-cache: false + - run: | + bundle install + bundle exec rspec spec/functional/resource/chocolatey_package_spec.rb userdefaults: strategy: fail-fast: false matrix: - os: [macos-10.15, macos-11] + os: [macos-11, macos-12] # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0' - ruby: [2.7, '3.0'] + ruby: ['3.1'] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - bundler-cache: true + bundler-cache: false + - run: bundle install - run: bundle exec rspec spec/functional/resource/macos_userdefaults_spec.rb diff --git a/.github/workflows/kitchen.yml b/.github/workflows/kitchen.yml index c66a5204ff..7296703467 100644 --- a/.github/workflows/kitchen.yml +++ b/.github/workflows/kitchen.yml @@ -13,37 +13,91 @@ jobs: fail-fast: false matrix: os: [windows-2022, windows-2019] + ruby: ['3.1'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 + - name: 'Upgrade Ruby Devkit on Windows' + id: upgrade_ruby + run: | + $pkg_version="3.1.2" + $pkg_revision="1" + $pkg_source="https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-${pkg_version}-${pkg_revision}/rubyinstaller-devkit-${pkg_version}-${pkg_revision}-x64.exe" + + $old_version = Ruby --version + if(-not($old_version -match "3.1")){ + $ErrorActionPreference = 'Stop'; + Write-Output 'Downloading Ruby + DevKit'; + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; + $package_destination = "$env:temp\rubyinstaller-devkit-$pkg_version-$pkg_revision-x64.exe" + (New-Object System.Net.WebClient).DownloadFile($pkg_source, $package_destination); + Write-Output "Did the file download?" + $output = Get-ChildItem -Path $env:temp + Write-Output $output + Write-Output 'Installing Ruby + DevKit'; + Start-Process $package_destination -ArgumentList '/verysilent /dir=C:\ruby31' -Wait ; + Write-Output 'Cleaning up installation'; + Remove-Item $package_destination -Force; + Write-Output "Installing URU to manage Ruby Versions" + choco install 7zip -y + Write-Output "Downloading Uru Installer..." + New-Item -Path c:\uru_temp -Type Directory + # Use TLS 1.2 for Windows 2016 Server and older + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Invoke-WebRequest -OutFile "c:\uru_temp\uru-0.8.5-windows-x86.7z" -Uri "https://bitbucket.org/jonforums/uru/downloads/uru-0.8.5-windows-x86.7z" + Write-Output "Installing Uru Ruby Switcher" + 7z x "c:\uru_temp\uru-0.8.5-windows-x86.7z" -o"C:\Program Files (x86)\Uru" + If ($lastexitcode -ne 0) { Exit $lastexitcode } + Start-Process "C:\Program Files (x86)\Uru\uru_rt.exe" -WorkingDirectory "C:\Program Files (x86)\Uru\" -ArgumentList 'admin install' -Wait + + Write-Output 'Updating PATH' + $env:PATH = "C:\Program Files (x86)\Uru;" + $env:PATH + [Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine) + + Write-Output "Register Installed Ruby Version 3.1 With Uru" + Start-Process "uru_rt.exe" -ArgumentList 'admin add C:\ruby31\bin' -Wait + uru 312 + if (-not $?) { throw "Can't Activate Ruby. Did Uru Registration Succeed?" } + ruby -v + if (-not $?) { throw "Can't run Ruby. Is it installed?" } + } + - name: 'Install Chef/Ohai from Omnitruck' id: install_chef run: | . { Invoke-WebRequest -useb https://omnitruck.chef.io/install.ps1 } | Invoke-Expression; Install-Project -project chef -channel current - $env:PATH = "C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;" + $env:PATH + $env:PATH = "C:\ruby31\bin;C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;" + $env:PATH chef-client -v ohai -v rake --version bundle -v - - name: 'Upgrade Chef/Ohai via Appbundler' - id: upgrade - run: | - $env:PATH = "C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;" + $env:PATH - $env:OHAI_VERSION = ( Select-String -Path .\Gemfile.lock -Pattern '(?<=ohai \()\d.*(?=\))' | ForEach-Object { $_.Matches[0].Value } ) - gem install appbundler appbundle-updater --no-doc - If ($lastexitcode -ne 0) { Exit $lastexitcode } - appbundle-updater chef chef $env:GITHUB_SHA --tarball --github $env:GITHUB_REPOSITORY - If ($lastexitcode -ne 0) { Exit $lastexitcode } - Write-Output "Installed Chef / Ohai release:" - chef-client -v - If ($lastexitcode -ne 0) { Exit $lastexitcode } - ohai -v - If ($lastexitcode -ne 0) { Exit $lastexitcode } + # - name: 'Upgrade Chef/Ohai via Appbundler' + # id: upgrade + # run: | + # $env:PATH = "C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;" + $env:PATH + # $env:OHAI_VERSION = ( Select-String -Path .\Gemfile.lock -Pattern '(?<=ohai \()\d.*(?=\))' | ForEach-Object { $_.Matches[0].Value } ) + + # # The chef-client installer does not put the file 'ansidecl.h' down in the correct location + # # This leads to failures during testing. Moving that file to its correct position here. + # # Another example of 'bad' that needs to be corrected + # $output = gci -path C:\opscode\ -file ansidecl.h -Recurse + # $target_path = $($output.Directory.Parent.FullName + "\x86_64-w64-mingw32\include") + # Move-Item -Path $output.FullName -Destination $target_path + + # gem install appbundler appbundle-updater --no-doc + # If ($lastexitcode -ne 0) { Exit $lastexitcode } + # appbundle-updater chef chef $env:GITHUB_SHA --tarball --github $env:GITHUB_REPOSITORY + # If ($lastexitcode -ne 0) { Exit $lastexitcode } + # Write-Output "Installed Chef / Ohai release:" + # chef-client -v + # If ($lastexitcode -ne 0) { Exit $lastexitcode } + # ohai -v + # If ($lastexitcode -ne 0) { Exit $lastexitcode } - name: 'Run end_to_end::default recipe' id: run run: | cd kitchen-tests - $env:PATH = "C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;" + $env:PATH + $env:PATH = "C:\ruby31\bin;C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;" + $env:PATH # htmldiff and ldiff on windows cause a conflict with gems being loaded below. # we remove thenm here. if (Test-Path C:\opscode\chef\embedded\bin\htmldiff) @@ -51,12 +105,6 @@ jobs: Remove-Item -Path C:\opscode\chef\embedded\bin\htmldiff Remove-Item -Path C:\opscode\chef\embedded\bin\ldiff } - # The chef-client installer does not put the file 'ansidecl.h' down in the correct location - # This leads to failures during testing. Moving that file to its correct position here. - # Another example of 'bad' that needs to be corrected - $output = gci -path C:\opscode\ -file ansidecl.h -Recurse - $target_path = $($output.Directory.Parent.FullName + "\x86_64-w64-mingw32\include") - Move-Item -Path $output.FullName -Destination $target_path bundle install --jobs=3 --retry=3 # If ($lastexitcode -ne 0) { Exit $lastexitcode } @@ -76,10 +124,18 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-10.15] # macos-11.0 is not public for now + os: [macos-latest] + ruby: ["3.1"] # macos-11.0 is not public for now runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 + with: + clean: true + - name: 'Upgrade Ruby Devkit on Macos' + id: upgrade_ruby + run: | + echo "This is the installed version of Ruby:" + brew info ruby - name: 'Install Chef/Ohai from Omnitruck' id: install_chef run: | @@ -88,26 +144,34 @@ jobs: /opt/chef/bin/chef-client -v /opt/chef/bin/ohai -v /opt/chef/embedded/bin/rake --version - /opt/chef/embedded/bin/bundle -v - - name: 'Upgrade Chef/Ohai via Appbundler' - id: upgrade - run: | - OHAI_VERSION=$(sed -n '/ohai .[0-9]/{s/.*(//;s/)//;p;}' Gemfile.lock) - sudo /opt/chef/embedded/bin/gem install appbundler appbundle-updater --no-doc - sudo /opt/chef/embedded/bin/appbundle-updater chef chef $GITHUB_SHA --tarball --github $GITHUB_REPOSITORY - echo "Installed Chef / Ohai release:" - /opt/chef/bin/chef-client -v - /opt/chef/bin/ohai -v + # echo "Updating Bundler" + # gem install bundler:2.3.18 + # echo "finished updating Bundler, now getting the version" + # /opt/chef/embedded/bin/bundle -v + # echo "finished getting the bundler version" - name: 'Run end_to_end::default recipe' id: run run: | + brew install rbenv ruby-build + touch ~/.zshrc + export PATH="$HOME/.rbenv/bin:$PATH" + export HOMEBREW_NO_ENV_HINTS="true" + echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc + source ~/.zshrc + rbenv install 3.1.2 + rbenv global 3.1.2 + gem install bundler:2.3.18 + echo "which bundler are we using?" + which bundle + echo "what version is that?" + bundle --version + cd /Users/runner/work/chef/chef + sudo bundle install cd kitchen-tests - sudo /opt/chef/embedded/bin/bundle config set --local without 'omnibus_package' - sudo /opt/chef/embedded/bin/bundle config set --local path 'vendor/bundle' - sudo /opt/chef/embedded/bin/bundle install --jobs=3 --retry=3 - sudo rm -f /opt/chef/embedded/bin/{htmldiff,ldiff} - sudo /opt/chef/embedded/bin/gem install berkshelf --no-doc - sudo /opt/chef/embedded/bin/berks vendor cookbooks + sudo bundle install --jobs=3 --retry=3 + sudo gem install kitchen + sudo gem install berkshelf --no-doc + sudo berks vendor cookbooks sudo /opt/chef/bin/chef-client -z -o end_to_end --chef-license accept-no-persist linux: @@ -127,20 +191,29 @@ jobs: - 'ubuntu-1804' - 'ubuntu-2004' - 'ubuntu-2204' + ruby: ['3.1'] runs-on: ubuntu-latest env: FORCE_FFI_YAJL: ext CHEF_LICENSE: accept-no-persist steps: - name: Check out code - uses: actions/checkout@main + uses: actions/checkout@v2 - name: Setup Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: "3.0" - bundler-cache: true + ruby-version: "3.1" + bundler-cache: false working-directory: kitchen-tests - name: Run Test Kitchen working-directory: kitchen-tests run: | + ruby -v + echo "Which ruby are we using?" + which ruby + cd /home/runner/work/chef/chef + bundle install + gem install kitchen + cd /home/runner/work/chef/chef/kitchen-tests + bundle install bundle exec kitchen test end-to-end-${{ matrix.os }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1b9daa6aba..6c71ae89c7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,10 +16,12 @@ jobs: - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 with: - ruby-version: 2.7 - bundler-cache: true + ruby-version: 3.1 + bundler-cache: false - uses: r7kamura/rubocop-problem-matchers-action@v1 # this shows the failures in the PR - - run: bundle exec chefstyle -c .rubocop.yml + - run: | + gem install chefstyle + chefstyle -c .rubocop.yml spellcheck: runs-on: ubuntu-latest diff --git a/.github/workflows/unit_specs.yml b/.github/workflows/unit_specs.yml index 38b884b5df..7efb9e31ee 100644 --- a/.github/workflows/unit_specs.yml +++ b/.github/workflows/unit_specs.yml @@ -9,18 +9,16 @@ name: unit_specs jobs: unit: - strategy: - fail-fast: false - matrix: - os: [macos-10.15] # macos-11.0 is not public for now - # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0' - ruby: ['3.0'] - runs-on: ${{ matrix.os }} + runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + with: + clean: true - uses: ruby/setup-ruby@v1 with: - ruby-version: ${{ matrix.ruby }} - bundler-cache: true + ruby-version: "3.1" + bundler-cache: false + - run: bundle update --bundler + - run: bundle install - run: bundle exec rake spec:unit - run: bundle exec rake component_specs diff --git a/.gitignore b/.gitignore index 0bb2f93da8..91ab9d6c77 100644 --- a/.gitignore +++ b/.gitignore @@ -81,7 +81,7 @@ chef-utils/pkg # knife knife/.bundle -knife/Gemfile.lock +#knife/Gemfile.lock We need this lockfile (for now) so that chef gets installed with windows gemspec under knife on windows platforms. knife/pkg knife/spec/data/test-dir knife/spec/data/nodes diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c8e2ab315..4e39a4022e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,84 @@ <!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ --> This changelog lists individual merged pull requests to Chef Infra Client and geared towards developers. For a list of significant changes per release see the [Chef Infra Client Release Notes](https://docs.chef.io/release_notes_client/). -<!-- latest_release 18.0.88 --> -## [v18.0.88](https://github.com/chef/chef/tree/v18.0.88) (2022-04-07) +<!-- latest_release 18.0.155 --> +## [v18.0.155](https://github.com/chef/chef/tree/v18.0.155) (2022-09-28) #### Merged Pull Requests -- Updating For Ruby 3.1 [#12769](https://github.com/chef/chef/pull/12769) ([johnmccrae](https://github.com/johnmccrae)) +- Disable platforms still under development [#13218](https://github.com/chef/chef/pull/13218) ([marcparadise](https://github.com/marcparadise)) <!-- latest_release --> <!-- release_rollup since=17.9.26 --> ### Changes not yet released to stable #### Merged Pull Requests +- Disable platforms still under development [#13218](https://github.com/chef/chef/pull/13218) ([marcparadise](https://github.com/marcparadise)) <!-- 18.0.155 --> +- Update to latest omnibus [#13216](https://github.com/chef/chef/pull/13216) ([marcparadise](https://github.com/marcparadise)) <!-- 18.0.154 --> +- Allow user providers to declare no support for ruby-shadow [#13213](https://github.com/chef/chef/pull/13213) ([marcparadise](https://github.com/marcparadise)) <!-- 18.0.153 --> +- Permit ruby 3.0 for AIX [#13207](https://github.com/chef/chef/pull/13207) ([marcparadise](https://github.com/marcparadise)) <!-- 18.0.152 --> +- Update Chef version in Gemfile.lock under knife [#13203](https://github.com/chef/chef/pull/13203) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.151 --> +- Separate gemspec for windows [#13202](https://github.com/chef/chef/pull/13202) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.150 --> +- Windows Verify Plan fails during "Rake Install rest-client" [#13199](https://github.com/chef/chef/pull/13199) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.149 --> +- Remove the chef17 git clone step [#13197](https://github.com/chef/chef/pull/13197) ([tpowell-progress](https://github.com/tpowell-progress)) <!-- 18.0.148 --> +- Update omnibus gem hash as well [#13198](https://github.com/chef/chef/pull/13198) ([tpowell-progress](https://github.com/tpowell-progress)) <!-- 18.0.147 --> +- Force omnibus version [#13193](https://github.com/chef/chef/pull/13193) ([tpowell-progress](https://github.com/tpowell-progress)) <!-- 18.0.146 --> +- Tweaking env variables in the config.yml file [#13178](https://github.com/chef/chef/pull/13178) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.145 --> +- Move Gemfile.locks to 2.3.7 and disable .github kitchen install of 2.3.18 [#13176](https://github.com/chef/chef/pull/13176) ([tpowell-progress](https://github.com/tpowell-progress)) <!-- 18.0.144 --> +- The worker container for expeditor needs to use Ruby 3.1.0 [#13171](https://github.com/chef/chef/pull/13171) ([PrajaktaPurohit](https://github.com/PrajaktaPurohit)) <!-- 18.0.143 --> +- Add empty pipeline for macos universal package [#13152](https://github.com/chef/chef/pull/13152) ([vkarve-chef](https://github.com/vkarve-chef)) <!-- 18.0.142 --> +- Add newline to end of sysctl files [#13118](https://github.com/chef/chef/pull/13118) ([tmccombs](https://github.com/tmccombs)) <!-- 18.0.141 --> +- fix chef_client_scheduled_task splay to accept 0 [#13095](https://github.com/chef/chef/pull/13095) ([Stromweld](https://github.com/Stromweld)) <!-- 18.0.140 --> +- add url for principal names [#13104](https://github.com/chef/chef/pull/13104) ([Stromweld](https://github.com/Stromweld)) <!-- 18.0.139 --> +- Added how to doc with details about documentation for infra client resources [#13046](https://github.com/chef/chef/pull/13046) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.138 --> +- Wording change in error for missing recipe dependency ("Obvious Fix") [#13061](https://github.com/chef/chef/pull/13061) ([c-drive](https://github.com/c-drive)) <!-- 18.0.137 --> +- Require etc library [#13068](https://github.com/chef/chef/pull/13068) ([curzonj](https://github.com/curzonj)) <!-- 18.0.136 --> +- Bump omnibus-software from `a9b13a0` to `1d540dc` in /omnibus [#13089](https://github.com/chef/chef/pull/13089) ([dependabot[bot]](https://github.com/dependabot[bot])) <!-- 18.0.135 --> +- Re add: Use new msys2 based devkit for windows"" [#13097](https://github.com/chef/chef/pull/13097) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.134 --> +- Skip tests on FreeBSD-13 [#13079](https://github.com/chef/chef/pull/13079) ([poorndm](https://github.com/poorndm)) <!-- 18.0.133 --> +- Add AIX-7.3 to Build Matrix [#13058](https://github.com/chef/chef/pull/13058) ([poorndm](https://github.com/poorndm)) <!-- 18.0.132 --> +- update property DSL docs [#13093](https://github.com/chef/chef/pull/13093) ([jasonwbarnett](https://github.com/jasonwbarnett)) <!-- 18.0.131 --> +- Revert "Use new msys2 based devkit for windows" [#13063](https://github.com/chef/chef/pull/13063) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.130 --> +- Fixed sensitive properties unsuppressed content issue [#13014](https://github.com/chef/chef/pull/13014) ([blabade](https://github.com/blabade)) <!-- 18.0.129 --> +- Fix issue in adhoc nightly builds [#13059](https://github.com/chef/chef/pull/13059) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.128 --> +- Use new msys2 based devkit for windows [#13038](https://github.com/chef/chef/pull/13038) ([mwrock](https://github.com/mwrock)) <!-- 18.0.127 --> +- Use dist constant when invoking knife configure [#12926](https://github.com/chef/chef/pull/12926) ([ramereth](https://github.com/ramereth)) <!-- 18.0.126 --> +- Add nightlies for chef-17 to run every Tue, Thu and chef-16 to run every Tue [#13018](https://github.com/chef/chef/pull/13018) ([PrajaktaPurohit](https://github.com/PrajaktaPurohit)) <!-- 18.0.125 --> +- AdHoc Pipeline Windows PageFile Test errors [#13009](https://github.com/chef/chef/pull/13009) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.124 --> +- Fix fedora kitchen test failure [#13020](https://github.com/chef/chef/pull/13020) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.123 --> +- Refactored tests for older Windows versions [#13019](https://github.com/chef/chef/pull/13019) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.122 --> +- Correcting Cert creation for rspec tests [#13010](https://github.com/chef/chef/pull/13010) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.121 --> +- Updated Ruby version in omnibus_overrides [#12995](https://github.com/chef/chef/pull/12995) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.120 --> +- Fix documentation for chef_client_scheduled_task [#12917](https://github.com/chef/chef/pull/12917) ([williamtheaker](https://github.com/williamtheaker)) <!-- 18.0.119 --> +- Zypper package source property addition [#12182](https://github.com/chef/chef/pull/12182) ([manick-vel-11](https://github.com/manick-vel-11)) <!-- 18.0.118 --> +- Smriti/3884 mounting cifs shares with spaces [#11626](https://github.com/chef/chef/pull/11626) ([msys-sgarg](https://github.com/msys-sgarg)) <!-- 18.0.117 --> +- Fix cron_d job name character set [#12377](https://github.com/chef/chef/pull/12377) ([hamarituc](https://github.com/hamarituc)) <!-- 18.0.116 --> +- Add CONTAINER_IMAGE dist constant [#12806](https://github.com/chef/chef/pull/12806) ([jakauppila](https://github.com/jakauppila)) <!-- 18.0.115 --> +- Stop executing locale-gen on every chef run by adding -h flag [#12833](https://github.com/chef/chef/pull/12833) ([hrak](https://github.com/hrak)) <!-- 18.0.114 --> +- KTLO - Updating authenticator.rb to correct for random password creation failures [#12980](https://github.com/chef/chef/pull/12980) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.113 --> +- refactoring the version check [#12988](https://github.com/chef/chef/pull/12988) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.112 --> +- Bumping license_scout version [#12992](https://github.com/chef/chef/pull/12992) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.111 --> +- Adjusting cert creation for older Windows platforms [#12965](https://github.com/chef/chef/pull/12965) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.110 --> +- Bump ohai to 18.0.14 [#12973](https://github.com/chef/chef/pull/12973) ([chef-expeditor[bot]](https://github.com/chef-expeditor[bot])) <!-- 18.0.109 --> +- Update the command to enable adhoc jobs for chef/chef main pipeline [#12979](https://github.com/chef/chef/pull/12979) ([PrajaktaPurohit](https://github.com/PrajaktaPurohit)) <!-- 18.0.108 --> +- Fix error 'error validating X-Vault-AWS-IAM-Server-ID header: missing header X-Vault-AWS-IAM-Server-ID' in Hashi Vault secret manager for AWS IAM auth method [#12956](https://github.com/chef/chef/pull/12956) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.107 --> +- Add nightly builds for chef/chef:main [#12971](https://github.com/chef/chef/pull/12971) ([PrajaktaPurohit](https://github.com/PrajaktaPurohit)) <!-- 18.0.106 --> +- Remove the beta feature warning which shows up when using Secret Manager [#12925](https://github.com/chef/chef/pull/12925) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.105 --> +- adding UCRT support to the build pipelines [#12959](https://github.com/chef/chef/pull/12959) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.104 --> +- Updated ncurses and gems [#12953](https://github.com/chef/chef/pull/12953) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.103 --> +- Updated files to account for pem storage in the Certificate Store [#12910](https://github.com/chef/chef/pull/12910) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.102 --> +- updated version data to properly account for Windows 11 and its assoc… [#12919](https://github.com/chef/chef/pull/12919) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.101 --> +- Knife upload: bad error message when a recipe has a syntax error [#11678](https://github.com/chef/chef/pull/11678) ([snehaldwivedi](https://github.com/snehaldwivedi)) <!-- 18.0.100 --> +- updating throw statement to only execute on non-zero exit codes [#12918](https://github.com/chef/chef/pull/12918) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.99 --> +- Refactoring Windows certificate code and tests to reflect updates in the win32-certstore gem [#12859](https://github.com/chef/chef/pull/12859) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.98 --> +- flush package cache after registering via rhsm_register [#12828](https://github.com/chef/chef/pull/12828) ([jasonwbarnett](https://github.com/jasonwbarnett)) <!-- 18.0.97 --> +- handling exception for compliance phase error during chef spec run [#12830](https://github.com/chef/chef/pull/12830) ([i5pranay93](https://github.com/i5pranay93)) <!-- 18.0.96 --> +- Renamed private method as conflicting to inbuilt method and getting warning [#12849](https://github.com/chef/chef/pull/12849) ([sanga1794](https://github.com/sanga1794)) <!-- 18.0.95 --> +- Bump berkshelf from 7.2.2 to 8.0.0 in /omnibus [#12837](https://github.com/chef/chef/pull/12837) ([dependabot[bot]](https://github.com/dependabot[bot])) <!-- 18.0.94 --> +- add expire and inactive options to linux user resource [#11659](https://github.com/chef/chef/pull/11659) ([Stromweld](https://github.com/Stromweld)) <!-- 18.0.93 --> +- Fix chef_client_config template rendering [#12817](https://github.com/chef/chef/pull/12817) ([jasonwbarnett](https://github.com/jasonwbarnett)) <!-- 18.0.92 --> +- main - Update bundle [#12788](https://github.com/chef/chef/pull/12788) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.91 --> +- Updates for the chef_client_config resource [#12732](https://github.com/chef/chef/pull/12732) ([chef-davin](https://github.com/chef-davin)) <!-- 18.0.90 --> +- SELinux integration to infra client [#12694](https://github.com/chef/chef/pull/12694) ([neha-p6](https://github.com/neha-p6)) <!-- 18.0.89 --> - Updating For Ruby 3.1 [#12769](https://github.com/chef/chef/pull/12769) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.88 --> - Updating gemfile.locks [#12751](https://github.com/chef/chef/pull/12751) ([johnmccrae](https://github.com/johnmccrae)) <!-- 18.0.87 --> - Rest Resource Support [#12755](https://github.com/chef/chef/pull/12755) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 18.0.86 --> diff --git a/CHEF_MVPS.md b/CHEF_MVPS.md index 98e0351c76..65696d54ab 100644 --- a/CHEF_MVPS.md +++ b/CHEF_MVPS.md @@ -24,7 +24,7 @@ Each year at ChefConf, a number of individuals are awarded the Awesome Community - [Bastien Jove](https://github.com/tensibai) - [Lance Albertson](https://github.com/ramereth) - [Marc Chamberland](https://github.com/bobchaos) -- [2019][USA](https://blog.chef.io/congratulations-to-our-2019-awesome-community-chefs/), [Europe](https://blog.chef.io/congratulations-to-our-chefconf-london-2019-award-winners/) +- 2019 [USA](https://blog.chef.io/congratulations-to-our-2019-awesome-community-chefs/), [Europe](https://blog.chef.io/congratulations-to-our-chefconf-london-2019-award-winners/) - [Graham Weldon](https://github.com/predominant) - [Jason Field](https://github.com/xorima) - [Joshua Basch](https://github.com/HT154) @@ -73,6 +73,7 @@ After receiving three MVP awards, we add someone to the hall of fame. We want to - Bryan Berry - Bryan McLellan - Jeff Blaine +- Phil Dibowitz ## The MVP recipients diff --git a/Dockerfile b/Dockerfile index 0a7459defc..5794ed202c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,7 @@ FROM busybox LABEL maintainer="Chef Software, Inc. <docker@chef.io>" ARG CHANNEL=stable -ARG VERSION=17.9.26 +ARG VERSION=18.0.146 ARG ARCH=x86_64 ARG PKG_VERSION=6 @@ -4,6 +4,10 @@ gem "chef", path: "." gem "ohai", git: "https://github.com/chef/ohai.git", branch: "main" +# Nwed to file a bug with rest-client. In the meantime, we can use this until they accept the update. +gem "rest-client", git: "https://github.com/chef/rest-client", branch: "jfm/ucrt_update1" + +gem "ffi", ">= 1.15.5" gem "chef-utils", path: File.expand_path("chef-utils", __dir__) if File.exist?(File.expand_path("chef-utils", __dir__)) gem "chef-config", path: File.expand_path("chef-config", __dir__) if File.exist?(File.expand_path("chef-config", __dir__)) @@ -20,7 +24,7 @@ gem "cheffish", ">= 17" group(:omnibus_package) do gem "appbundler" gem "rb-readline" - gem "inspec-core-bin", "~> 4.24" # need to provide the binaries for inspec + gem "inspec-core-bin", ">= 5" # need to provide the binaries for inspec gem "chef-vault" end @@ -54,10 +58,11 @@ group(:development, :test) do gem "fauxhai-ng" # for chef-utils gem end -group(:chefstyle) do - # for testing new chefstyle rules - gem "chefstyle", git: "https://github.com/chef/chefstyle.git", branch: "main" -end +gem "chefstyle" +# group(:chefstyle) do +# # for testing new chefstyle rules +# gem "chefstyle", git: "https://github.com/chef/chefstyle.git", branch: "main" +# end instance_eval(ENV["GEMFILE_MOD"]) if ENV["GEMFILE_MOD"] diff --git a/Gemfile.lock b/Gemfile.lock index 627d945590..c0eb7b22c9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,12 +1,4 @@ GIT - remote: https://github.com/chef/chefstyle.git - revision: 71ae97744713ffd91ac8277d7a1385dabb6d570b - branch: main - specs: - chefstyle (2.2.2) - rubocop (= 1.25.1) - -GIT remote: https://github.com/chef/ohai.git revision: 3855db320bf14766e37eaeb1bb61ba87c2542ac8 branch: main @@ -43,38 +35,38 @@ GIT netrc (~> 0.8) GIT - remote: https://github.com/chef/ruby-proxifier - revision: 8b87d0b5b469adbd93eabc0d20f3e47007aef743 - branch: lcg/ruby-3 - specs: - proxifier (1.0.3) - -GIT remote: https://github.com/chef/ruby-shadow revision: 3b8ea40b0e943b5de721d956741308ce805a5c3c branch: lcg/ruby-3.0 specs: ruby-shadow (2.5.0) +GIT + remote: https://github.com/chef/ruby-proxifier + revision: 8b87d0b5b469adbd93eabc0d20f3e47007aef743 + branch: lcg/ruby-3 + specs: + proxifier (1.0.3) + PATH remote: . specs: - chef (18.0.88) + chef (18.0.155) addressable aws-sdk-s3 (~> 1.91) aws-sdk-secretsmanager (~> 1.46) - chef-config (= 18.0.88) - chef-utils (= 18.0.88) + chef-config (= 18.0.155) + chef-utils (= 18.0.155) chef-vault chef-zero (>= 14.0.11) corefoundation (~> 0.3.4) diff-lcs (>= 1.2.4, < 1.6.0, != 1.4.0) erubis (~> 2.7) - ffi (>= 1.5.0) + ffi (>= 1.15.5) ffi-libarchive (~> 1.0, >= 1.0.3) ffi-yajl (~> 2.2) iniparse (~> 1.4) - inspec-core (~> 4.23) + inspec-core (>= 5) license-acceptance (>= 1.0.5, < 3) mixlib-archive (>= 0.4, < 2.0) mixlib-authentication (>= 2.1, < 4) @@ -87,28 +79,29 @@ PATH plist (~> 3.2) proxifier (~> 1.0) syslog-logger (~> 1.6) - train-core (~> 3.2, >= 3.2.28) + train-core (~> 3.10, >= 3.2.28) train-rest (>= 0.4.1) train-winrm (>= 0.2.5) + unf_ext (>= 0.0.8.2) uuidtools (>= 2.1.5, < 3.0) vault (~> 0.16) - chef (18.0.88-universal-mingw32) + chef (18.0.155-x64-mingw-ucrt) addressable aws-sdk-s3 (~> 1.91) aws-sdk-secretsmanager (~> 1.46) - chef-config (= 18.0.88) + chef-config (= 18.0.155) chef-powershell (~> 1.0.12) - chef-utils (= 18.0.88) + chef-utils (= 18.0.155) chef-vault chef-zero (>= 14.0.11) corefoundation (~> 0.3.4) diff-lcs (>= 1.2.4, < 1.6.0, != 1.4.0) erubis (~> 2.7) - ffi (>= 1.5.0) + ffi (>= 1.15.5) ffi-libarchive (~> 1.0, >= 1.0.3) ffi-yajl (~> 2.2) iniparse (~> 1.4) - inspec-core (~> 4.23) + inspec-core (>= 5) iso8601 (>= 0.12.1, < 0.14) license-acceptance (>= 1.0.5, < 3) mixlib-archive (>= 0.4, < 2.0) @@ -122,13 +115,14 @@ PATH plist (~> 3.2) proxifier (~> 1.0) syslog-logger (~> 1.6) - train-core (~> 3.2, >= 3.2.28) + train-core (~> 3.10, >= 3.2.28) train-rest (>= 0.4.1) train-winrm (>= 0.2.5) + unf_ext (>= 0.0.8.2) uuidtools (>= 2.1.5, < 3.0) vault (~> 0.16) - win32-api (~> 1.5) - win32-certstore (~> 0.6.2) + win32-api (~> 1.10.0) + win32-certstore (~> 0.6.15) win32-event (~> 0.6.1) win32-eventlog (= 0.6.3) win32-mmap (~> 0.4.1) @@ -141,15 +135,15 @@ PATH PATH remote: chef-bin specs: - chef-bin (18.0.88) - chef (= 18.0.88) + chef-bin (18.0.155) + chef (= 18.0.155) PATH remote: chef-config specs: - chef-config (18.0.88) + chef-config (18.0.155) addressable - chef-utils (= 18.0.88) + chef-utils (= 18.0.155) fuzzyurl mixlib-config (>= 2.2.12, < 4.0) mixlib-shellout (>= 2.0, < 4.0) @@ -158,7 +152,7 @@ PATH PATH remote: chef-utils specs: - chef-utils (18.0.88) + chef-utils (18.0.155) concurrent-ruby GEM @@ -211,6 +205,8 @@ GEM chef-utils (>= 17.0) chef-zero (>= 14.0) net-ssh + chefstyle (2.2.2) + rubocop (= 1.25.1) coderay (1.1.3) concurrent-ruby (1.1.10) corefoundation (0.3.13) @@ -263,7 +259,7 @@ GEM domain_name (~> 0.5) httpclient (2.8.3) iniparse (1.5.0) - inspec-core (4.56.20) + inspec-core (5.18.14) addressable (~> 2.4) chef-telemetry (~> 1.0, >= 1.0.8) faraday (>= 0.9.0, < 1.5) @@ -283,11 +279,11 @@ GEM sslshake (~> 1.2) thor (>= 0.20, < 2.0) tomlrb (>= 1.2, < 2.1) - train-core (~> 3.0) + train-core (~> 3.10) tty-prompt (~> 0.17) tty-table (~> 0.10) - inspec-core-bin (4.56.20) - inspec-core (= 4.56.20) + inspec-core-bin (5.18.14) + inspec-core (= 5.18.14) ipaddress (0.8.3) iso8601 (0.13.0) jmespath (1.6.1) @@ -308,8 +304,6 @@ GEM mime-types-data (3.2022.0105) mixlib-archive (1.1.7) mixlib-log - mixlib-archive (1.1.7-universal-mingw32) - mixlib-log mixlib-authentication (3.0.10) mixlib-cli (2.1.8) mixlib-config (3.0.27) @@ -317,11 +311,6 @@ GEM mixlib-log (3.0.9) mixlib-shellout (3.2.7) chef-utils - mixlib-shellout (3.2.7-universal-mingw32) - chef-utils - ffi-win32-extensions (~> 1.0.3) - win32-process (~> 0.9) - wmi-lite (~> 1.0) mixlib-shellout (3.2.7-x64-mingw-ucrt) chef-utils ffi-win32-extensions (~> 1.0.3) @@ -357,7 +346,7 @@ GEM pry-stack_explorer (0.6.1) binding_of_caller (~> 1.0) pry (~> 0.13) - public_suffix (5.0.0) + public_suffix (4.0.7) rack (2.2.4) rainbow (3.1.1) rake (13.0.6) @@ -456,11 +445,10 @@ GEM crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) webrick (1.7.0) - win32-api (1.10.1-universal-mingw32) + win32-api (1.10.1) win32-certstore (0.6.15) chef-powershell (>= 1.0.12) ffi - mixlib-shellout win32-event (0.6.3) win32-ipc (>= 0.6.0) win32-eventlog (0.6.3) @@ -502,9 +490,7 @@ GEM PLATFORMS ruby - x64-mingw32 - x64-unknown - x86-mingw32 + x64-mingw-ucrt DEPENDENCIES appbundler @@ -514,10 +500,11 @@ DEPENDENCIES chef-utils! chef-vault cheffish (>= 17) - chefstyle! + chefstyle ed25519 (~> 1.2) fauxhai-ng - inspec-core-bin (~> 4.24) + ffi (>= 1.15.5) + inspec-core-bin (>= 5) ohai! proxifier! pry (= 0.13.0) @@ -525,9 +512,10 @@ DEPENDENCIES pry-stack_explorer rake rb-readline + rest-client! rspec ruby-shadow! webmock BUNDLED WITH - 2.3.7 + 2.3.18 @@ -40,7 +40,7 @@ namespace :pre_install do %w{chef-utils chef-config}.each do |gem| path = ::File.join(::File.dirname(__FILE__), gem) Dir.chdir(path) do - sh("rake install") + system "rake install" end end end @@ -61,16 +61,16 @@ end # hack in all the preinstall tasks to occur before the traditional install task task install: "pre_install:all" - # make sure we build the correct gemspec on windows -gemspec = Gem.win_platform? ? "chef-universal-mingw32" : "chef" +gemspec = Gem.win_platform? ? "chef-universal-mingw-ucrt" : "chef" + Bundler::GemHelper.install_tasks name: gemspec # this gets appended to the normal bundler install helper task :install do chef_bin_path = ::File.join(::File.dirname(__FILE__), "chef-bin") Dir.chdir(chef_bin_path) do - sh("rake install:force") + system "rake install:force" end end @@ -80,7 +80,7 @@ namespace :install do task :local do chef_bin_path = ::File.join(::File.dirname(__FILE__), "chef-bin") Dir.chdir(chef_bin_path) do - sh("rake install:local") + system "rake install:local" end end end @@ -1 +1 @@ -18.0.88
\ No newline at end of file +18.0.155
\ No newline at end of file diff --git a/bin/knife b/bin/knife deleted file mode 100755 index aebc0f72d7..0000000000 --- a/bin/knife +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env ruby -# -# ./knife - Chef CLI interface -# -# Author:: Adam Jacob (<adam@chef.io>) -# Copyright:: Copyright 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. - -$:.unshift(File.expand_path(File.join(__dir__, "..", "lib"))) -require "chef/application/knife" - -Chef::Application::Knife.new.run diff --git a/chef-bin/lib/chef-bin/version.rb b/chef-bin/lib/chef-bin/version.rb index ccaadbb2a8..f62078a5de 100644 --- a/chef-bin/lib/chef-bin/version.rb +++ b/chef-bin/lib/chef-bin/version.rb @@ -21,7 +21,7 @@ module ChefBin CHEFBIN_ROOT = File.expand_path("..", __dir__) - VERSION = "18.0.88".freeze + VERSION = "18.0.155".freeze end # diff --git a/chef-config/lib/chef-config/version.rb b/chef-config/lib/chef-config/version.rb index 4703f2c93f..cbeb1ed1c3 100644 --- a/chef-config/lib/chef-config/version.rb +++ b/chef-config/lib/chef-config/version.rb @@ -15,5 +15,5 @@ module ChefConfig CHEFCONFIG_ROOT = File.expand_path("..", __dir__) - VERSION = "18.0.88".freeze + VERSION = "18.0.155".freeze end diff --git a/chef-config/lib/chef-config/workstation_config_loader.rb b/chef-config/lib/chef-config/workstation_config_loader.rb index ea42211120..a77670ddb2 100644 --- a/chef-config/lib/chef-config/workstation_config_loader.rb +++ b/chef-config/lib/chef-config/workstation_config_loader.rb @@ -17,6 +17,7 @@ # require "chef-utils" unless defined?(ChefUtils::CANARY) +require "etc" unless defined?(Etc) require_relative "config" require_relative "exceptions" require_relative "logger" diff --git a/chef-universal-mingw32.gemspec b/chef-universal-mingw-ucrt.gemspec index c869ac2384..2edfd751f9 100644 --- a/chef-universal-mingw32.gemspec +++ b/chef-universal-mingw-ucrt.gemspec @@ -1,8 +1,8 @@ -gemspec = eval(IO.read(File.expand_path("chef.gemspec", __dir__))) +gemspec = instance_eval(File.read(File.expand_path("chef.gemspec", __dir__))) -gemspec.platform = Gem::Platform.new(%w{universal mingw32}) +gemspec.platform = Gem::Platform.new(%w{x64-mingw-ucrt}) -gemspec.add_dependency "win32-api", "~> 1.5" +gemspec.add_dependency "win32-api", "~> 1.10.0" gemspec.add_dependency "win32-event", "~> 0.6.1" # TODO: Relax this pin and make the necessary updaets. The issue originally # leading to this pin has been fixed in 0.6.5. @@ -14,9 +14,10 @@ gemspec.add_dependency "win32-service", ">= 2.1.5", "< 3.0" gemspec.add_dependency "wmi-lite", "~> 1.0" gemspec.add_dependency "win32-taskscheduler", "~> 2.0" gemspec.add_dependency "iso8601", ">= 0.12.1", "< 0.14" # validate 0.14 when it comes out -gemspec.add_dependency "win32-certstore", "~> 0.6.2" # 0.5+ required for specifying user vs. system store +gemspec.add_dependency "win32-certstore", "~> 0.6.15" # 0.5+ required for specifying user vs. system store gemspec.add_dependency "chef-powershell", "~> 1.0.12" # The guts of the powershell_exec code have been moved to its own gem, chef-powershell. It's part of the chef-powershell-shim repo. + gemspec.extensions << "ext/win32-eventlog/Rakefile" gemspec.files += Dir.glob("{distro,ext}/**/*") -gemspec +gemspec
\ No newline at end of file diff --git a/chef-utils/lib/chef-utils/dist.rb b/chef-utils/lib/chef-utils/dist.rb index fb2292ecfd..a3d8a27d0e 100644 --- a/chef-utils/lib/chef-utils/dist.rb +++ b/chef-utils/lib/chef-utils/dist.rb @@ -64,6 +64,9 @@ module ChefUtils # The client's gem GEM = "chef" + + # The client's container image + CONTAINER_REF = "chef/chef" end class Inspec diff --git a/chef-utils/lib/chef-utils/version.rb b/chef-utils/lib/chef-utils/version.rb index d527d6a3df..af9ebf6a47 100644 --- a/chef-utils/lib/chef-utils/version.rb +++ b/chef-utils/lib/chef-utils/version.rb @@ -16,5 +16,5 @@ module ChefUtils CHEFUTILS_ROOT = File.expand_path("..", __dir__) - VERSION = "18.0.88" + VERSION = "18.0.155" end diff --git a/chef-utils/spec/unit/dsl/platform_family_spec.rb b/chef-utils/spec/unit/dsl/platform_family_spec.rb index c4363c8e8d..a2f268e307 100644 --- a/chef-utils/spec/unit/dsl/platform_family_spec.rb +++ b/chef-utils/spec/unit/dsl/platform_family_spec.rb @@ -210,7 +210,7 @@ RSpec.describe ChefUtils::DSL::PlatformFamily do end context "node-independent windows APIs" do - if RUBY_PLATFORM.match?(/mswin|mingw32|windows/) + if RUBY_PLATFORM.match?(/mswin|mingw|windows/) it "reports true for :windows_ruby?" do expect(described_class.windows_ruby?).to be true end diff --git a/chef.gemspec b/chef.gemspec index 4a3092168f..a9ea748b65 100644 --- a/chef.gemspec +++ b/chef.gemspec @@ -22,11 +22,15 @@ Gem::Specification.new do |s| s.email = "adam@chef.io" s.homepage = "https://www.chef.io" - s.required_ruby_version = ">= 2.6.0" + if RUBY_PLATFORM =~ /aix/ + s.required_ruby_version = ">= 3.0.3" + else + s.required_ruby_version = ">= 3.1.0" + end s.add_dependency "chef-config", "= #{Chef::VERSION}" s.add_dependency "chef-utils", "= #{Chef::VERSION}" - s.add_dependency "train-core", "~> 3.2", ">= 3.2.28" # 3.2.28 fixes sudo prompts. See https://github.com/chef/chef/pull/9635 + s.add_dependency "train-core", "~> 3.10", ">= 3.2.28" # 3.2.28 fixes sudo prompts. See https://github.com/chef/chef/pull/9635 s.add_dependency "train-winrm", ">= 0.2.5" s.add_dependency "train-rest", ">= 0.4.1" # target mode with rest APIs @@ -37,9 +41,9 @@ Gem::Specification.new do |s| s.add_dependency "mixlib-shellout", ">= 3.1.1", "< 4.0" s.add_dependency "mixlib-archive", ">= 0.4", "< 2.0" s.add_dependency "ohai", "~> 18.0" - s.add_dependency "inspec-core", "~> 4.23" + s.add_dependency "inspec-core", ">= 5" - s.add_dependency "ffi", ">= 1.5.0" + s.add_dependency "ffi", ">= 1.15.5" s.add_dependency "ffi-yajl", "~> 2.2" s.add_dependency "net-sftp", ">= 2.1.2", "< 4.0" # remote_file resource s.add_dependency "net-ftp" # remote_file resource @@ -54,6 +58,7 @@ Gem::Specification.new do |s| s.add_dependency "addressable" s.add_dependency "syslog-logger", "~> 1.6" s.add_dependency "uuidtools", ">= 2.1.5", "< 3.0" # osx_profile resource + s.add_dependency "unf_ext", ">= 0.0.8.2" # This is ruby31 compatible ucrt gem version s.add_dependency "corefoundation", "~> 0.3.4" # macos_userdefaults resource s.add_dependency "proxifier", "~> 1.0" diff --git a/cspell.json b/cspell.json index 681d67fc76..3bbdfbc5e1 100644 --- a/cspell.json +++ b/cspell.json @@ -14,6 +14,7 @@ "dictionaries": ["chef"], // words - list of words to be always considered correct "words": [ + "CIFS", "abcz", "abdulin", "ABORTIFHUNG", @@ -21,6 +22,7 @@ "activationkey", "ADAP", "addlock", + "addormodify", "addrs", "ADMINI", "adminonly", @@ -164,6 +166,7 @@ "CHEFUTILS", "chefzero", "chgrpmem", + "childitem", "CHINESEBIG", "ckbk", "cksum", @@ -321,6 +324,7 @@ "ecparam", "edir", "egid", + "egrep", "ELOOP", "EMBEDDEDNT", "EMBEDDEDSERVER", @@ -366,7 +370,9 @@ "faststart", "faststop", "fatals", + "Fcontext", "fcntl", + "fcontext", "featurename", "FFLAGS", "fflags", @@ -389,6 +395,7 @@ "fmri", "fname", "foorb", + "FORCECLOSEAPPLICATIONS", "FORCEMINIMIZE", "FORCEOFFFEEDBACK", "FORCEONFEEDBACK", @@ -408,6 +415,7 @@ "getaddrinfo", "getbinaryfile", "getc", + "getenforce", "GETFD", "GETFL", "getgrgid", @@ -422,6 +430,7 @@ "getprint", "getprocaddr", "getremotelogin", + "getsebool", "getspnam", "gettext", "GETTHUMBPRINTCODE", @@ -522,6 +531,7 @@ "imageinfo", "Immutablize", "immutablize", + "inact", "includedir", "includepkgs", "includer", @@ -582,7 +592,9 @@ "keyivgen", "KEYNAME", "keyname", + "keypair", "keyscan", + "keysign", "KEYTAB", "keytab", "kool", @@ -610,6 +622,7 @@ "lgrpi", "LGRPID", "LHND", + "libselinux", "linuxmint", "LISTBOX", "listprop", @@ -730,6 +743,7 @@ "MONTHLYDATE", "MONTHLYDOW", "monthlydow", + "moodle", "mountpoint", "mounttab", "mpkg", @@ -919,6 +933,7 @@ "PDWORD", "PDWORDLONG", "performant", + "permissives", "PFILETIME", "PFLOAT", "PGENERICMAPPING", @@ -946,8 +961,10 @@ "plutil", "PNAME", "Policybuilder", + "policycoreutils", "POLICYNAME", "portageq", + "portcon", "PORTVERSION", "POSI", "POST'ing", @@ -976,6 +993,7 @@ "PRINTPROCESSOR", "PRINTQ", "PROCNUM", + "processname", "procs", "progname", "PROMPTSTRUCT", @@ -1026,6 +1044,7 @@ "rcscript", "rcvar", "RDWR", + "readdir", "readlink", "realloc", "realname", @@ -1049,6 +1068,7 @@ "Referer", "regen", "regexes", + "regextype", "REGSAM", "reimplement", "reimplementing", @@ -1125,6 +1145,7 @@ "Scriptable", "SCROLLBAR", "SCROLLBARS", + "secontext", "secoption", "secopts", "secp", @@ -1134,7 +1155,12 @@ "secvalue", "SEGDPL", "SEGLIM", + "seinfo", "selinuxenabled", + "SELINUXTYPE", + "selinuxtype", + "semanage", + "semodule", "SEPCHARS", "SERENUM", "sertelon", @@ -1148,13 +1174,17 @@ "SESSIONCHANGE", "SESSIONID", "SETCOUNT", + "setenforce", "SETFD", "SETFL", + "SETLOCALDEFS", "setlocal", "SETMARK", "setobj", "setprop", "setremotelogin", + "setools", + "setsebool", "setsid", "settimezone", "SETTINGCHANGE", @@ -1187,6 +1217,7 @@ "signedheaderauth", "SIGQUIT", "SIGUSR", + "silentlycontinue", "SINGLELINE", "singleline", "Singleuser", @@ -1269,6 +1300,7 @@ "swappable", "symlinking", "syntaxcache", + "sysadm", "sysconfig", "sysctld", "sysctls", @@ -1285,6 +1317,7 @@ "TBYTE", "TCBS", "TCHAR", + "tempadmin", "tempcron", "tempdir", "Tempfile", @@ -1342,6 +1375,7 @@ "unformatter", "unhold", "unignored", + "unins", "uninst", "unintuitive", "unixy", @@ -1437,6 +1471,7 @@ "wchar", "wchars", "WEBHOSTING", + "webroot", "webserver", "whatavailable", "whateverd", @@ -1445,6 +1480,7 @@ "whatinstalled", "whatprovides", "whereis", + "whoami", "willem", "WINAPI", "winbase", diff --git a/docs/dev/how_to/adding_documentation_to_infra_resources.md b/docs/dev/how_to/adding_documentation_to_infra_resources.md new file mode 100644 index 0000000000..7a333fa35f --- /dev/null +++ b/docs/dev/how_to/adding_documentation_to_infra_resources.md @@ -0,0 +1,29 @@ +# Adding documentation to resources: +The documentation for Infra Client resources resides at [chef-wed-docs repository](https://github.com/chef/chef-web-docs/). +Currently in order to reflect the documentation added to Infra Client resources on the [website](https://docs.chef.io/) we need to follow some manual steps. + +# Prerequisite: +Clone [chef-wed-docs repository](https://github.com/chef/chef-web-docs/). Install Hugo, npm, go. + +`brew tap go-swagger/go-swagger && brew install go-swagger hugo node go jq` + +# Generating YAML files: +The YAML data is generated using a [rake](https://github.com/chef/chef/blob/main/tasks/docs.rb) task in the `chef/chef` repository. + +`rake docs_site:resources` + +The YAML files will be created under `docs_site` directory. Copy the corresponding file(s) for the resource(s) for which documentation is updated to [chef-web-docs/data/infra/resources](https://github.com/chef/chef-web-docs/tree/main/data/infra/resources). +(NOTE: The data file(.yaml) should be verified and edited manually to remove any inaccuracies.) + +# Generating mark down(.md) files: +Go to the [chef-web-docs](https://github.com/chef/chef-web-docs/) repository, where we copied the YAML file(s). +Using the YAML file(s) create corresponding markdown(.md) file(s). + +`hugo new -k resource content/resources/RESOURCE_NAME.md` + +# Verifying changes locally: +Run server locally and verify the changes in your browser at http://localhost:1313 + +`make serve` + +Once changes are verified, create a PR at [chef-web-docs](https://github.com/chef/chef-web-docs/) repository.
\ No newline at end of file diff --git a/habitat/plan.ps1 b/habitat/plan.ps1 index 92fedfbc60..83312c4345 100644 --- a/habitat/plan.ps1 +++ b/habitat/plan.ps1 @@ -12,7 +12,7 @@ $pkg_bin_dirs=@( ) $pkg_deps=@( "core/cacerts" - "chef/ruby30-plus-devkit" + "chef/ruby31-plus-devkit" "chef/chef-powershell-shim" ) @@ -42,9 +42,12 @@ function Invoke-Download() { # source is in this repo, so we're going to create an archive from the # appropriate path within the repo and place the generated tarball in the # location expected by do_unpack + $git_path += "c:\\Program Files\\Git\\bin" try { Push-Location (Resolve-Path "$PLAN_CONTEXT/../").Path - git archive --format=zip --output="${HAB_CACHE_SRC_PATH}/${pkg_filename}" HEAD + [System.Diagnostics.Process]::Start("$git_path\\git", "archive --format=zip --output=${HAB_CACHE_SRC_PATH}\\${pkg_filename} HEAD") + Start-Sleep -Seconds 30 + # getting an error about the archive being in use, adding the sleep to let other handles on the file finish. if (-not $?) { throw "unable to create archive of source" } } finally { Pop-Location @@ -61,11 +64,17 @@ function Invoke-Prepare { try { Push-Location "${HAB_CACHE_SRC_PATH}/${pkg_dirname}" - + Write-BuildLine " ** Where the hell is 'Gem'?" + $gem_file = @" +@ECHO OFF +@"%~dp0ruby.exe" "%~dpn0" %* +"@ + $gem_file | Set-Content "$PWD\\gem.bat" + $env:Path += ";c:\\Program Files\\Git\\bin" + gem install bundler:2.3.17 Write-BuildLine " ** Configuring bundler for this build environment" bundle config --local without server docgen maintenance pry travis integration ci chefstyle if (-not $?) { throw "unable to configure bundler to restrict gems to be installed" } - bundle config --local jobs 4 bundle config --local retry 5 bundle config --local silence_root_warning 1 } finally { @@ -77,7 +86,7 @@ function Invoke-Build { try { Push-Location "${HAB_CACHE_SRC_PATH}/${pkg_dirname}" - $env:_BUNDER_WINDOWS_DLLS_COPIED = "1" + $env:_BUNDLER_WINDOWS_DLLS_COPIED = "1" Write-BuildLine " ** Using bundler to retrieve the Ruby dependencies" bundle install --jobs=3 --retry=3 @@ -87,19 +96,31 @@ function Invoke-Build { try { Push-Location $git_gem Write-BuildLine " -- installing $git_gem" - rake install # this needs to NOT be 'bundle exec'd else bundler complains about dev deps not being installed - if (-not $?) { throw "unable to install $git_gem as a plain old gem" } + # The rest client doesn't have an 'Install' task so it bombs out when we call Rake Install for it + # Happily, its Rakefile ultimately calls 'gem build' to build itself with. We're doing that here. + if ($git_gem -match "rest-client"){ + $gemspec_path = $git_gem.ToString() + "\rest-client.windows.gemspec" + gem build $gemspec_path + $gem_path = $git_gem.ToString() + "\rest-client*.gem" + gem install $gem_path + } + else { + rake install $git_gem --trace=stdout # this needs to NOT be 'bundle exec'd else bundler complains about dev deps not being installed + } + if (-not $?) { throw "unable to install $($git_gem) as a plain old gem" } } finally { Pop-Location } } Write-BuildLine " ** Running the chef project's 'rake install' to install the path-based gems so they look like any other installed gem." - bundle exec rake install:local # this needs to be 'bundle exec'd because a Rakefile makes reference to Bundler - if (-not $?) { - Write-Warning " -- That didn't work. Let's try again." - bundle exec rake install:local # this needs to be 'bundle exec'd because a Rakefile makes reference to Bundler - if (-not $?) { throw "unable to install the gems that live in directories within this repo" } - } + $install_attempt = 0 + do { + Start-Sleep -Seconds 5 + $install_attempt++ + Write-BuildLine "Install attempt $install_attempt" + bundle exec rake install:local --trace=stdout + } while ((-not $?) -and ($install_attempt -lt 5)) + } finally { Pop-Location } diff --git a/habitat/plan.sh b/habitat/plan.sh index 7a9e6343c7..43ce851852 100644 --- a/habitat/plan.sh +++ b/habitat/plan.sh @@ -1,4 +1,4 @@ -_chef_client_ruby="core/ruby30" +_chef_client_ruby="core/ruby31" pkg_name="chef-infra-client" pkg_origin="chef" pkg_maintainer="The Chef Maintainers <humans@chef.io>" diff --git a/kitchen-tests/cookbooks/end_to_end/metadata.rb b/kitchen-tests/cookbooks/end_to_end/metadata.rb index 71ddd0d6e3..2f623df90c 100644 --- a/kitchen-tests/cookbooks/end_to_end/metadata.rb +++ b/kitchen-tests/cookbooks/end_to_end/metadata.rb @@ -11,7 +11,6 @@ depends "nscd" depends "ntp" depends "openssh" depends "resolver" -depends "selinux" depends "users", "< 7.1" # 7.1 breaks macos / opensuse depends "git" diff --git a/kitchen-tests/cookbooks/end_to_end/recipes/_chef_client_trusted_certificate.rb b/kitchen-tests/cookbooks/end_to_end/recipes/_chef_client_trusted_certificate.rb index 94e6cedde8..e085519c4a 100644 --- a/kitchen-tests/cookbooks/end_to_end/recipes/_chef_client_trusted_certificate.rb +++ b/kitchen-tests/cookbooks/end_to_end/recipes/_chef_client_trusted_certificate.rb @@ -1,10 +1,10 @@ chef_client_trusted_certificate "self-signed.badssl.com" do certificate <<~CERT -----BEGIN CERTIFICATE----- -MIIDeTCCAmGgAwIBAgIJAMnA8BB8xT6wMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV +MIIDeTCCAmGgAwIBAgIJAMtEwC/G1C5xMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp c2NvMQ8wDQYDVQQKDAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTAeFw0y -MTEwMTEyMDAzNTRaFw0yMzEwMTEyMDAzNTRaMGIxCzAJBgNVBAYTAlVTMRMwEQYD +MjA4MTIxNTU5MTBaFw0yNDA4MTExNTU5MTBaMGIxCzAJBgNVBAYTAlVTMRMwEQYD VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQK DAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAMIE7PiM7gTCs9hQ1XBYzJMY61yoaEmwIrX5lZ6xKyx2 @@ -14,12 +14,12 @@ xPxTuW1CrbV8/q71FdIzSOciccfCFHpsKOo3St/qbLVytH5aohbcabFXRNsKEqve ww9HdFxBIuGa+RuT5q0iBikusbpJHAwnnqP7i/dAcgCskgjZjFeEU4EFy+b+a1SY QCeFxxC7c3DvaRhBB0VVfPlkPz0sw6l865MaTIbRyoUCAwEAAaMyMDAwCQYDVR0T BAIwADAjBgNVHREEHDAaggwqLmJhZHNzbC5jb22CCmJhZHNzbC5jb20wDQYJKoZI -hvcNAQELBQADggEBAC4DensZ5tCTeCNJbHABYPwwqLUFOMITKOOgF3t8EqOan0CH -ST1NNi4jPslWrVhQ4Y3UbAhRBdqXl5N/NFfMzDosPpOjFgtifh8Z2s3w8vdlEZzf -A4mYTC8APgdpWyNgMsp8cdXQF7QOfdnqOfdnY+pfc8a8joObR7HEaeVxhJs+XL4E -CLByw5FR+svkYgCbQGWIgrM1cRpmXemt6Gf/XgFNP2PdubxqDEcnWlTMk8FCBVb1 -nVDSiPjYShwnWsOOshshCRCAiIBPCKPX0QwKDComQlRrgMIvddaSzFFTKPoNZjC+ -CUspSNnL7V9IIHvqKlRSmu+zIpm2VJCp1xLulk8= +hvcNAQELBQADggEBAKgnD+Ak7ttVfKvriYAsf4ttTYfOuyLfAr4hTTSXLN2u1ySD +fIpqSyeOkiEwfD5Bt7C/muEXEIyG/y6/C/ozb5JBvdd8c7zicLmaHtZtZbj4+H1b +/gqaBHuvWxiRR91bbgNaKsPMGCWiAvUt4/+y8z6xefUS+aKeFNhYjdwyFIr17j3Q +gxGpgCbYLLIoewP+Oj6xvZgGl6vj0xW9a4144xjFo1o1vqWkj+3IZGmnZ/jyznWd +5XzZCUaM9z6nn7NVxQZEelk885Q3oUxY96rRO+IUA8Vnk3iEtOdZPbNBaZwvgkfz +4vhvM8gKbdeeWoOAJDLzDZiDrUpKtIkBcLuJ7Cw= -----END CERTIFICATE----- CERT end diff --git a/kitchen-tests/cookbooks/end_to_end/recipes/_dmg_package.rb b/kitchen-tests/cookbooks/end_to_end/recipes/_dmg_package.rb index 27dad15c80..d51ccdc681 100644 --- a/kitchen-tests/cookbooks/end_to_end/recipes/_dmg_package.rb +++ b/kitchen-tests/cookbooks/end_to_end/recipes/_dmg_package.rb @@ -11,11 +11,11 @@ dmg_package "LittleSecrets" do action :install end -dmg_package "virtualbox" do - app "virtualbox" - source "http://download.virtualbox.org/virtualbox/6.1.8/VirtualBox-6.1.8-137981-OSX.dmg" - checksum "569e91eb3c7cb002d407b236a7aa71ac610cf2ad1afa03730dab11fbd4b89e7c" - type "pkg" - accept_eula true - allow_untrusted true -end +# dmg_package "virtualbox" do +# app "virtualbox" +# source "http://download.virtualbox.org/virtualbox/6.1.8/VirtualBox-6.1.8-137981-OSX.dmg" +# checksum "569e91eb3c7cb002d407b236a7aa71ac610cf2ad1afa03730dab11fbd4b89e7c" +# type "pkg" +# accept_eula true +# allow_untrusted true +# end diff --git a/kitchen-tests/cookbooks/end_to_end/recipes/linux.rb b/kitchen-tests/cookbooks/end_to_end/recipes/linux.rb index f306a22164..52b165d04c 100644 --- a/kitchen-tests/cookbooks/end_to_end/recipes/linux.rb +++ b/kitchen-tests/cookbooks/end_to_end/recipes/linux.rb @@ -28,7 +28,11 @@ timezone "America/Los_Angeles" include_recipe "::_yum" if platform_family?("rhel") if platform_family?("rhel", "fedora", "amazon") - include_recipe "selinux::disabled" + selinux_install "selinux" + + selinux_state "permissive" do + action :permissive + end end build_essential do @@ -43,6 +47,7 @@ include_recipe "ntp" unless fedora? # fedora 34+ doesn't have NTP resolver_config "/etc/resolv.conf" do nameservers [ "8.8.8.8", "8.8.4.4" ] search [ "chef.io" ] + atomic_update false # otherwise EBUSY for linux docker containers end users_from_databag = search("users", "*:*") @@ -57,7 +62,7 @@ ssh_known_hosts_entry "github.com" include_recipe "openssh" -include_recipe "nscd" +include_recipe "nscd" unless fedora? # fedora 34+ doesn't have nscd logrotate_package "logrotate" diff --git a/kitchen-tests/cookbooks/end_to_end/recipes/windows.rb b/kitchen-tests/cookbooks/end_to_end/recipes/windows.rb index d37174edd2..0c60bf1b0f 100644 --- a/kitchen-tests/cookbooks/end_to_end/recipes/windows.rb +++ b/kitchen-tests/cookbooks/end_to_end/recipes/windows.rb @@ -13,6 +13,59 @@ chef_sleep "2" execute "dir" +execute "Print git version" do + command "git --version & git --exec-path" + live_stream true +end + +# FIXME Uninstall git using powershell +# this is a temporary band-aid due to the fallback git version in +# https://github.com/sous-chefs/git defaulting to an older version of git +# than will be installed on the current image this runs in for GitHub Actions +powershell_script "uninstall_git" do + code <<-EOH + $possibleInstalledPaths = @("C:/Program Files/Git/", "C:/Program Files (x64)/Git/", "c:/git/") + $foundAnInstallation = $false + ### For all places where Git "could" be. + foreach ($installPath in $possibleInstalledPaths) + { + ### If the path where Git could exist + if (Test-Path($installPath)) + { + ## Some Git stuff might be running.. kill them. + Stop-Process -processname Bash -erroraction 'silentlycontinue' + Stop-Process -processname Putty* -erroraction 'silentlycontinue' + + $foundAnInstallation = $true + Write-Host "Removing Git from " $installPath + + ### Find if there's an uninstaller in the folder. + $uninstallers = Get-ChildItem $installPath"unins*.exe" + + ### In reality, there should only be just one that matches. + foreach ($uninstaller in $uninstallers) + { + ### Invoke the uninstaller. + $uninstallerCommandLineOptions = "/SP- /VERYSILENT /SUPPRESSMSGBOXES /FORCECLOSEAPPLICATIONS" + Start-Process -Wait -FilePath $uninstaller -ArgumentList $uninstallerCommandLineOptions + } + + ### Remove the folder if it didn't clean up properly. + if (Test-Path($installPath)) + { + Remove-Item -Recurse -Force $installPath + } + } + } + + if (!($foundAnInstallation)) + { + Write-Host "No git installation found. Nothing to uninstall" + } + EOH + live_stream true +end + powershell_script "sleep 1 second" do code "Start-Sleep -s 1" live_stream true diff --git a/knife/Gemfile.lock b/knife/Gemfile.lock new file mode 100644 index 0000000000..a0114c1048 --- /dev/null +++ b/knife/Gemfile.lock @@ -0,0 +1,37 @@ +PATH + remote: .. + specs: + chef (18.0.155) + chef (18.0.155-x64-mingw-ucrt) + +PLATFORMS + ruby + x64-mingw-ucrt + +DEPENDENCIES + appbundler + chef! + chef-bin! + chef-config! + chef-utils! + chef-vault + cheffish (>= 17) + chefstyle + ed25519 (~> 1.2) + fauxhai-ng + ffi (>= 1.15.5) + inspec-core-bin (>= 5) + ohai! + proxifier! + pry (= 0.13.0) + pry-byebug + pry-stack_explorer + rake + rb-readline + rest-client! + rspec + ruby-shadow! + webmock + +BUNDLED WITH + 2.3.18
\ No newline at end of file diff --git a/knife/knife.gemspec b/knife/knife.gemspec index 445ab92b44..aac58d4bf7 100644 --- a/knife/knife.gemspec +++ b/knife/knife.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |s| s.email = "adam@chef.io" # These seem a bit out of date, and this address probably doesn't go anywhere anymore? s.homepage = "https://www.chef.io" - s.required_ruby_version = ">= 2.7.0" + s.required_ruby_version = ">= 3.1.0" s.add_dependency "chef-config", ">= #{Chef::Knife::VERSION.split(".").first}" s.add_dependency "chef-utils", ">= #{Chef::Knife::VERSION.split(".").first}" @@ -23,7 +23,7 @@ Gem::Specification.new do |s| s.add_dependency "license-acceptance", ">= 1.0.5", "< 3" s.add_dependency "mixlib-cli", ">= 2.1.1", "< 3.0" s.add_dependency "mixlib-archive", ">= 0.4", "< 2.0" - s.add_dependency "ohai", ">= 17.0", "< 19" + s.add_dependency "ohai", "~> 18.0" s.add_dependency "ffi", ">= 1.15" # 1.14 versions are broken on i386 windows s.add_dependency "ffi-yajl", "~> 2.2" s.add_dependency "net-ssh", ">= 5.1", "< 7" diff --git a/knife/lib/chef/knife/configure.rb b/knife/lib/chef/knife/configure.rb index 9c806b4af6..e49a01277c 100644 --- a/knife/lib/chef/knife/configure.rb +++ b/knife/lib/chef/knife/configure.rb @@ -138,7 +138,7 @@ class Chef # @return [String] the path to the user's .chef directory def chef_config_path - @chef_config_path ||= ChefConfig::PathHelper.home(".chef") + @chef_config_path ||= ChefConfig::PathHelper.home(ChefUtils::Dist::Infra::USER_CONF_DIR) end # @return [String] the full path to the config file (credential file) diff --git a/knife/lib/chef/knife/core/ui.rb b/knife/lib/chef/knife/core/ui.rb index 782df1ca10..9eda4615f5 100644 --- a/knife/lib/chef/knife/core/ui.rb +++ b/knife/lib/chef/knife/core/ui.rb @@ -233,7 +233,7 @@ class Chef tf.sync = true tf.puts output tf.close - raise "Please set EDITOR environment variable. See https://docs.chef.io/knife_setup/ for details." unless system("#{config[:editor]} #{tf.path}") + raise "Please set EDITOR environment variable. See https://docs.chef.io/workstation/knife_setup/#setting-your-text-editor for details." unless system("#{config[:editor]} #{tf.path}") output = IO.read(tf.path) end diff --git a/knife/lib/chef/knife/edit.rb b/knife/lib/chef/knife/edit.rb index 45702d168b..87e19b1583 100644 --- a/knife/lib/chef/knife/edit.rb +++ b/knife/lib/chef/knife/edit.rb @@ -74,7 +74,7 @@ class Chef # Let the user edit the temporary file unless system("#{config[:editor]} #{file.path}") - raise "Please set EDITOR environment variable. See https://docs.chef.io/knife_setup/ for details." + raise "Please set EDITOR environment variable. See https://docs.chef.io/workstation/knife_setup/#setting-your-text-editor for details." end result_text = IO.read(file.path) diff --git a/knife/lib/chef/knife/supermarket_install.rb b/knife/lib/chef/knife/supermarket_install.rb index c979a4d6f4..91b71df9ff 100644 --- a/knife/lib/chef/knife/supermarket_install.rb +++ b/knife/lib/chef/knife/supermarket_install.rb @@ -156,7 +156,7 @@ class Chef def convert_path(upstream_file) # converts a Windows path (C:\foo) to a mingw path (/c/foo) - if ENV["MSYSTEM"] == "MINGW32" + if ENV["MSYSTEM"] == ( "MINGW32" || "UCRT64" ) upstream_file.sub(/^([[:alpha:]]):/, '/\1') else Shellwords.escape upstream_file diff --git a/knife/lib/chef/knife/user_edit.rb b/knife/lib/chef/knife/user_edit.rb index fff8c6b70f..8b937189df 100644 --- a/knife/lib/chef/knife/user_edit.rb +++ b/knife/lib/chef/knife/user_edit.rb @@ -81,7 +81,7 @@ class Chef f.sync = true f.puts output f.close - raise "Please set EDITOR environment variable. See https://docs.chef.io/knife_setup/ for details." unless system("#{config[:editor]} #{f.path}") + raise "Please set EDITOR environment variable. See https://docs.chef.io/workstation/knife_setup/#setting-your-text-editor for details." unless system("#{config[:editor]} #{f.path}") edited_user = JSON.parse(IO.read(f.path)) end diff --git a/knife/lib/chef/knife/version.rb b/knife/lib/chef/knife/version.rb index 49e5e0b6fd..2c9363bf90 100644 --- a/knife/lib/chef/knife/version.rb +++ b/knife/lib/chef/knife/version.rb @@ -17,7 +17,7 @@ class Chef class Knife KNIFE_ROOT = File.expand_path("../..", __dir__) - VERSION = "18.0.88".freeze + VERSION = "18.0.155".freeze end end diff --git a/knife/spec/support/platform_helpers.rb b/knife/spec/support/platform_helpers.rb index 4d3acbcb33..1f36a0fbcc 100644 --- a/knife/spec/support/platform_helpers.rb +++ b/knife/spec/support/platform_helpers.rb @@ -127,6 +127,10 @@ def freebsd? RUBY_PLATFORM.include?("freebsd") end +def freebsd_gte_12_3? + RUBY_PLATFORM.include?("freebsd") && !!(ohai[:platform_version].to_f >= 12.3) +end + def intel_64bit? !!(ohai[:kernel][:machine] == "x86_64") end diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 07798798b9..e5fcd56eb0 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -715,6 +715,70 @@ class Chef pfx end + def update_key_and_register(cert_name) + self.class.update_key_and_register(cert_name) + end + + def self.update_key_and_register(cert_name, expiring_cert = nil) + # Chef client and node objects exist on Chef Server already + # Create a new public/private keypair in secure storage + # and register the new public cert with Chef Server + require "time" unless defined?(Time) + autoload :URI, "uri" + + node = Chef::Config[:node_name] + end_date = Time.new + (3600 * 24 * 90) + end_date = end_date.utc.iso8601 + + new_cert_name = Time.now.utc.iso8601 + payload = { + name: new_cert_name, + clientname: node, + public_key: "", + expiration_date: end_date, + } + + new_pfx = generate_pfx_package(cert_name, end_date) + payload[:public_key] = new_pfx.certificate.public_key.to_pem + base_url = "#{Chef::Config[:chef_server_url]}" + + @tmpdir = Dir.mktmpdir + file_path = File.join(@tmpdir, "#{node}.pem") + + # The pfx files expire every 90 days. + # We check them in /http/authenticator to see if they are expiring when we extract the private key + # If they are, we come here to update Chef Server with a new public key + if expiring_cert + File.open(file_path, "w") { |f| f.write expiring_cert.key.to_pem } + signing_cert = file_path + client = Chef::ServerAPI.new(base_url, client_name: Chef::Config[:node_name], signing_key_filename: signing_cert ) + File.delete(file_path) + else + client = Chef::ServerAPI.new(base_url, client_name: Chef::Config[:node_name], signing_key_filename: Chef::Config[:client_key] ) + end + + # Get the list of keys for this client + # Then add the new key we just created + # Then we delete the old one. + cert_list = client.get(base_url + "/clients/#{node}/keys") + client.post(base_url + "/clients/#{node}/keys", payload) + + # We want to remove the old key for various reasons + # In the case where more than 1 certificate is returned we assume + # there is some special condition applied to the client so we won't delete the old + # certificates + if cert_list.count < 2 + cert_hash = cert_list.reduce({}, :merge!) + old_cert_name = cert_hash["name"] + new_key = new_pfx.key.to_pem + File.open(file_path, "w") { |f| f.write new_key } + client = Chef::ServerAPI.new(base_url, client_name: Chef::Config[:node_name], signing_key_filename: file_path) + client.delete(base_url + "/clients/#{node}/keys/#{old_cert_name}") + File.delete(file_path) + end + import_pfx_to_store(new_pfx) + end + def create_new_key_and_register(cert_name) require "time" unless defined?(Time) autoload :URI, "uri" diff --git a/lib/chef/compliance/input_collection.rb b/lib/chef/compliance/input_collection.rb index 034943f8d9..a3e55c5f6a 100644 --- a/lib/chef/compliance/input_collection.rb +++ b/lib/chef/compliance/input_collection.rb @@ -40,7 +40,7 @@ class Chef def from_file(filename, cookbook_name) new_input = Input.from_file(events, filename, cookbook_name) self << new_input - events.compliance_input_loaded(new_input) + events&.compliance_input_loaded(new_input) end # Add a input from a raw hash. This input will be enabled by default. diff --git a/lib/chef/compliance/profile_collection.rb b/lib/chef/compliance/profile_collection.rb index d85d04e825..2def655dd9 100644 --- a/lib/chef/compliance/profile_collection.rb +++ b/lib/chef/compliance/profile_collection.rb @@ -41,11 +41,10 @@ class Chef def from_file(path, cookbook_name) new_profile = Profile.from_file(events, path, cookbook_name) self << new_profile - events.compliance_profile_loaded(new_profile) + events&.compliance_profile_loaded(new_profile) end # @return [Boolean] if any of the profiles are enabled - # def using_profiles? any?(&:enabled?) end diff --git a/lib/chef/compliance/waiver_collection.rb b/lib/chef/compliance/waiver_collection.rb index a3d12b3a97..68dce07287 100644 --- a/lib/chef/compliance/waiver_collection.rb +++ b/lib/chef/compliance/waiver_collection.rb @@ -40,7 +40,7 @@ class Chef def from_file(filename, cookbook_name) new_waiver = Waiver.from_file(events, filename, cookbook_name) self << new_waiver - events.compliance_waiver_loaded(new_waiver) + events&.compliance_waiver_loaded(new_waiver) end # Add a waiver from a raw hash. This waiver will be enabled by default. diff --git a/lib/chef/cookbook/syntax_check.rb b/lib/chef/cookbook/syntax_check.rb index 555d2f6715..914e2947ca 100644 --- a/lib/chef/cookbook/syntax_check.rb +++ b/lib/chef/cookbook/syntax_check.rb @@ -248,8 +248,8 @@ class Chef # Debugs ruby syntax errors by printing the path to the file and any # diagnostic info given in +error_message+ def invalid_ruby_file(ruby_file, error_message) - file_relative_path = ruby_file[/^#{Regexp.escape(cookbook_path + File::Separator)}(.*)/, 1] - Chef::Log.fatal("Cookbook file #{file_relative_path} has a ruby syntax error:") + file_relative_path = ruby_file[ruby_file.index(cookbook_path.split("/").last), ruby_file.length] + Chef::Log.fatal("Cookbook file #{file_relative_path} has a ruby syntax error.") error_message.each_line { |l| Chef::Log.fatal(l.chomp) } false end diff --git a/lib/chef/dsl/secret.rb b/lib/chef/dsl/secret.rb index 2377ae36fe..04ca2b2adf 100644 --- a/lib/chef/dsl/secret.rb +++ b/lib/chef/dsl/secret.rb @@ -162,10 +162,6 @@ class Chef # value = secret(name: "test1", service: :aws_secrets_manager, version: "v1", config: { region: "us-west-1" }) # log "My secret is #{value}" def secret(name: nil, version: nil, service: default_secret_service, config: default_secret_config) - Chef::Log.warn <<~EOM.gsub("\n", " ") - The secrets Chef Infra language helper is currently in beta. If you have feedback or you would - like to be part of the future design of this helper e-mail us at secrets_management_beta@progress.com" - EOM sensitive(true) if is_a?(Chef::Resource) Chef::SecretFetcher.for_service(service, config, run_context).fetch(name, version) end diff --git a/lib/chef/http/authenticator.rb b/lib/chef/http/authenticator.rb index 3b9d49f42a..c795297397 100644 --- a/lib/chef/http/authenticator.rb +++ b/lib/chef/http/authenticator.rb @@ -26,8 +26,6 @@ class Chef class HTTP class Authenticator DEFAULT_SERVER_API_VERSION = "2".freeze - # cspell:disable-next-line - SOME_CHARS = "~!@#%^&*_-+=`|\\(){}[<]:;'>,.?/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".each_char.to_a extend Chef::Mixin::PowershellExec @@ -190,8 +188,9 @@ class Chef unless @win32registry.key_exists?(new_path) @win32registry.create_key(new_path, true) end + require "securerandom" unless defined?(SecureRandom) size = 14 - password = SOME_CHARS.sample(size).join + password = SecureRandom.alphanumeric(size) encrypted_pass = encrypt_pfx_pass(password) values = { name: "PfxPass", type: :string, data: encrypted_pass } @win32registry.set_value(new_path, values) @@ -228,12 +227,16 @@ class Chef file_path = ps_blob["PSPath"].split("::")[1] pkcs = OpenSSL::PKCS12.new(File.binread(file_path), password) - # We test the pfx we just extracted the private key from + # We check the pfx we just extracted the private key from # if that cert is expiring in 7 days or less we generate a new pfx/p12 object # then we post the new public key from that to the client endpoint on # chef server. - # is_certificate_expiring(pkcs) File.delete(file_path) + key_expiring = is_certificate_expiring?(pkcs) + if key_expiring + powershell_exec!(delete_old_key_ps(client_name)) + ::Chef::Client.update_key_and_register(Chef::Config[:client_name], pkcs) + end return pkcs.key.private_to_pem end @@ -242,6 +245,12 @@ class Chef false end + def self.is_certificate_expiring?(pkcs) + today = Date.parse(Time.now.utc.iso8601) + future = Date.parse(pkcs.certificate.not_after.iso8601) + future.mjd - today.mjd <= 7 + end + def self.get_the_key_ps(client_name, password) powershell_code = <<~CODE Try { @@ -256,6 +265,12 @@ class Chef CODE end + def self.delete_old_key_ps(client_name) + powershell_code = <<~CODE + Get-ChildItem -path cert:\\LocalMachine\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } | Remove-Item -ErrorAction Stop; + CODE + end + def authentication_headers(method, url, json_body = nil, headers = nil) request_params = { http_method: method, diff --git a/lib/chef/mixin/properties.rb b/lib/chef/mixin/properties.rb index c42e3889b0..4e00a09002 100644 --- a/lib/chef/mixin/properties.rb +++ b/lib/chef/mixin/properties.rb @@ -274,6 +274,12 @@ class Chef result end + # This method returns list of sensitive properties + # @return [Array<Property>] All sensitive properties. + def sensitive_properties + properties.values.empty? ? [] : properties.values.select(&:sensitive?) + end + # Returns the name of the name property. Returns nil if there is no name property. # # @return [Symbol] the name property for this resource diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 0813005845..1d91495397 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -113,9 +113,11 @@ class Chef # and the transformed value returned as output. Lazy values will *not* # be passed to this method until after they are evaluated. Called in the # context of the resource (meaning you can access other properties). - # @option options [Boolean] :required `true` if this property - # must be present; `false` otherwise. This is checked after the resource - # is fully initialized. + # @option options [Boolean, Array<Symbol>] :required `true` if this property + # must be present for *all* actions; `false` otherwise. Alternatively + # you may specify a list of actions the property is required for, when + # the property is only required for a subset of actions. This is checked + # after the resource is fully initialized. # @option options [String] :deprecated If set, this property is deprecated and # will create a deprecation warning. # diff --git a/lib/chef/provider/group/windows.rb b/lib/chef/provider/group/windows.rb index dacfc348f7..e0fc3b6034 100644 --- a/lib/chef/provider/group/windows.rb +++ b/lib/chef/provider/group/windows.rb @@ -17,7 +17,7 @@ # require_relative "../user" -if RUBY_PLATFORM.match?(/mswin|mingw32|windows/) +if RUBY_PLATFORM.match?(/mswin|mingw|windows/) require_relative "../../util/windows/net_group" end diff --git a/lib/chef/provider/mount/linux.rb b/lib/chef/provider/mount/linux.rb index 83fbfab957..899053b613 100644 --- a/lib/chef/provider/mount/linux.rb +++ b/lib/chef/provider/mount/linux.rb @@ -71,6 +71,11 @@ class Chef when /\A#{Regexp.escape(real_mount_point)}\s+#{device_mount_regex}\[/ mounted = true logger.trace("Network device #{device_logstring} mounted as #{real_mount_point}") + # Permalink for network device mounted with a space in device name https://rubular.com/r/CK5zWWms96CRES + # See the comment in "device_with_space_escape" for an explanation what's going here. + when /\A#{Regexp.escape(real_mount_point)}\s+#{device_with_space_escape}\s/ + mounted = true + logger.trace("Network device #{device_logstring} mounted as #{real_mount_point}") end end @current_resource.mounted(mounted) diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb index 2bc9d2c78f..2021d6ece5 100644 --- a/lib/chef/provider/mount/mount.rb +++ b/lib/chef/provider/mount/mount.rb @@ -217,6 +217,14 @@ class Chef end end + def device_with_space_escape + # For CIFS (and perhaps other remote network mounts) when a space is in the "device name" + # It will appear with the space substituted with a special character. However, when mounting, + # The mount needs to be done with an actual space. This function provides the device name with + # The special character to determine if the device is mounted. + device_mount_regex.gsub(" ", "\\x20") + end + def device_mount_regex if network_device? # ignore trailing slash diff --git a/lib/chef/provider/mount/windows.rb b/lib/chef/provider/mount/windows.rb index 5b68417ab0..c5d29245c2 100644 --- a/lib/chef/provider/mount/windows.rb +++ b/lib/chef/provider/mount/windows.rb @@ -17,7 +17,7 @@ # require_relative "../mount" -if RUBY_PLATFORM.match?(/mswin|mingw32|windows/) +if RUBY_PLATFORM.match?(/mswin|mingw|windows/) require_relative "../../util/windows/net_use" require_relative "../../util/windows/volume" end diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb index bb76eacc56..a6da1e16cf 100644 --- a/lib/chef/provider/package/rubygems.rb +++ b/lib/chef/provider/package/rubygems.rb @@ -92,7 +92,7 @@ class Chef # def installed_versions(gem_dep) rubygems_version = Gem::Version.new(Gem::VERSION) - if rubygems_version >= Gem::Version.new("2.7") + if rubygems_version >= Gem::Version.new("3.1") # In newer Rubygems, bundler is now a "default gem" which means # even with AlternateGemEnvironment when you try to get the # installed versions, you get the one from Chef's Ruby's default diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb index 47e85a83d0..9cd95aade7 100644 --- a/lib/chef/provider/package/zypper.rb +++ b/lib/chef/provider/package/zypper.rb @@ -20,17 +20,28 @@ require_relative "../package" require_relative "../../resource/zypper_package" +require_relative "zypper/version" class Chef class Provider class Package class Zypper < Chef::Provider::Package use_multipackage_api + use_package_name_for_source allow_nils provides :package, platform_family: "suse" provides :zypper_package + def define_resource_requirements + super + requirements.assert(:install, :upgrade) do |a| + a.assertion { source_files_exist? } + a.failure_message Chef::Exceptions::Package, "#{new_resource} source file(s) do not exist: #{missing_sources}" + a.whyrun "Assuming they would have been previously created." + end + end + def load_current_resource @current_resource = Chef::Resource::ZypperPackage.new(new_resource.name) current_resource.package_name(new_resource.package_name) @@ -70,7 +81,35 @@ class Chef end def candidate_version - @candidate_version ||= package_name_array.each_with_index.map { |pkg, i| available_version(i) } + package_name_array.each_with_index.map do |pkg, i| + available_version(i) + end + end + + # returns true if all sources exist. Returns false if any do not, or if no + # sources were specified. + # @return [Boolean] True if all sources exist + def source_files_exist? + if !new_resource.source.nil? + resolved_source_array.all? { |s| s && ::File.exist?(s) } + else + true + end + end + + # Helper to return all the names of the missing sources for error messages. + # @return [Array<String>] Array of missing sources + def missing_sources + resolved_source_array.select { |s| s.nil? || !::File.exist?(s) } + end + + def resolve_source_to_version + shell_out!("rpm -qp --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n' #{new_resource.source}").stdout.each_line do |line| + case line + when /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/ + return Version.new($1, "#{$2 == "(none)" ? "0" : $2}:#{$3}-#{$4}", $5) + end + end end def resolve_current_version(package_name) @@ -119,7 +158,12 @@ class Chef def available_version(index) @available_version ||= [] - @available_version[index] ||= resolve_available_version(package_name_array[index], safe_version_array[index]) + + @available_version[index] ||= if new_resource.source + resolve_source_to_version + else + resolve_available_version(package_name_array[index], safe_version_array[index]) + end @available_version[index] end @@ -141,7 +185,7 @@ class Chef end def zypper_package(command, global_options, *options, names, versions) - zipped_names = zip(names, versions) + zipped_names = new_resource.source || zip(names, versions) if zypper_version < 1.0 shell_out!("zypper", global_options, gpg_checks, command, *options, "-y", names) else diff --git a/lib/chef/provider/package/zypper/version.rb b/lib/chef/provider/package/zypper/version.rb new file mode 100644 index 0000000000..8c430c9d66 --- /dev/null +++ b/lib/chef/provider/package/zypper/version.rb @@ -0,0 +1,60 @@ +# +# Copyright:: Copyright (c) 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. +# + +class Chef + class Provider + class Package + class Zypper < Chef::Provider::Package + + # helper class to assist in passing around name/version/arch triples + class Version + attr_accessor :name + attr_accessor :version + attr_accessor :arch + + def initialize(name, version, arch) + @name = name + @version = version + @arch = arch + end + + def to_s + "#{name}-#{version}.#{arch}" unless version.nil? + end + + def version_with_arch + "#{version}.#{arch}" unless version.nil? + end + + def name_with_arch + "#{name}.#{arch}" unless name.nil? + end + + def matches_name_and_arch?(other) + other.version == version && other.arch == arch + end + + def ==(other) + name == other.name && version == other.version && arch == other.arch + end + + alias eql? == + end + end + end + end +end diff --git a/lib/chef/provider/user.rb b/lib/chef/provider/user.rb index 61de2127bb..3d18c0df82 100644 --- a/lib/chef/provider/user.rb +++ b/lib/chef/provider/user.rb @@ -66,14 +66,23 @@ class Chef end current_resource.comment(user_info.gecos) - if new_resource.password && current_resource.password == "x" - begin - require "shadow" - rescue LoadError - @shadow_lib_ok = false - else - shadow_info = Shadow::Passwd.getspnam(new_resource.username) - current_resource.password(shadow_info.sp_pwdp) + begin + require "shadow" + rescue LoadError + @shadow_lib_ok = false + else + @shadow_info = Shadow::Passwd.getspnam(new_resource.username) + # This conditional remains in place until we can sort out whether we need it. + # Currently removing it causes tests to fail, but that /seems/ to be mocking/setup issues. + # Some notes for context: + # 1. Ruby's ETC.getpwnam makes use of /etc/passwd file (https://github.com/ruby/etc/blob/master/ext/etc/etc.c), + # which returns "x" for a nil password. on AIX it returns a "*" + # (https://www.ibm.com/docs/bg/aix/7.2?topic=passwords-using-etcpasswd-file) + # 2. On AIX platforms ruby_shadow does not work as it does not + # store encrypted passwords in the /etc/passwd file but in /etc/security/passwd file. + # The AIX provider for user currently declares it does not support ruby-shadow. + if new_resource.password && current_resource.password == "x" + current_resource.password(@shadow_info.sp_pwdp) end end @@ -83,6 +92,27 @@ class Chef current_resource end + # An overridable for platforms that do not support ruby shadow. This way we + # can verify that the platform supports ruby shadow before requiring that + # it be available. + def supports_ruby_shadow? + true + end + + def load_shadow_options + unless @shadow_info.nil? + current_resource.inactive(@shadow_info.sp_inact&.to_i) + # sp_expire gives time since epoch in days till expiration. Need to convert that + # to time in seconds since epoch and output date format for comparison + expire_date = if @shadow_info.sp_expire.nil? + @shadow_info.sp_expire + else + Time.at(@shadow_info.sp_expire * 60 * 60 * 24).strftime("%Y-%m-%d") + end + current_resource.expire_date(expire_date) + end + end + def define_resource_requirements requirements.assert(:create, :modify, :manage, :lock, :unlock) do |a| a.assertion { @group_name_resolved } @@ -90,11 +120,17 @@ class Chef a.whyrun "group name #{new_resource.gid} does not exist. This will cause group assignment to fail. Assuming this group will have been created previously." end requirements.assert(:all_actions) do |a| - a.assertion { @shadow_lib_ok } + a.assertion { !supports_ruby_shadow? || @shadow_lib_ok } a.failure_message Chef::Exceptions::MissingLibrary, "You must have ruby-shadow installed for password support!" a.whyrun "ruby-shadow is not installed. Attempts to set user password will cause failure. Assuming that this gem will have been previously installed." \ "Note that user update converge may report false-positive on the basis of mismatched password. " end + requirements.assert(:all_actions) do |a| + # either neither linux-only value is set, or we need to be on Linux. + a.assertion { (!new_resource.expire_date && !new_resource.inactive) || linux? } + a.failure_message Chef::Exceptions::User, "Properties expire_date and inactive are not supported by this OS or have not been implemented for this OS yet." + a.whyrun "Properties expire_date and inactive are ignored as they are not supported by this OS or have not been implemented yet for this OS" + end requirements.assert(:modify, :lock, :unlock) do |a| a.assertion { @user_exists } a.failure_message(Chef::Exceptions::User, "Cannot modify user #{new_resource.username} - does not exist!") diff --git a/lib/chef/provider/user/aix.rb b/lib/chef/provider/user/aix.rb index 740f9943d3..997bd6bac5 100644 --- a/lib/chef/provider/user/aix.rb +++ b/lib/chef/provider/user/aix.rb @@ -23,6 +23,11 @@ class Chef provides :user, os: "aix" provides :aix_user + # The ruby-shadow gem is not supported on aix. + def supports_ruby_shadow? + false + end + def create_user shell_out!("useradd", universal_options, useradd_options, new_resource.username) add_password diff --git a/lib/chef/provider/user/linux.rb b/lib/chef/provider/user/linux.rb index 40b5985cb1..ab411d769a 100644 --- a/lib/chef/provider/user/linux.rb +++ b/lib/chef/provider/user/linux.rb @@ -23,6 +23,22 @@ class Chef provides :linux_user provides :user, os: "linux" + def load_current_resource + super + load_shadow_options + end + + def compare_user + super + %i{expire_date inactive}.each do |user_attrib| + new_val = new_resource.send(user_attrib) + cur_val = current_resource.send(user_attrib) + if !new_val.nil? && new_val.to_s != cur_val.to_s + @change_desc << "change #{user_attrib} from #{cur_val} to #{new_val}" + end + end + end + def create_user shell_out!("useradd", universal_options, useradd_options, new_resource.username) end @@ -52,7 +68,9 @@ class Chef def universal_options opts = [] opts << "-c" << new_resource.comment if should_set?(:comment) + opts << "-e" << new_resource.expire_date if prop_is_set?(:expire_date) opts << "-g" << new_resource.gid if should_set?(:gid) + opts << "-f" << new_resource.inactive if prop_is_set?(:inactive) opts << "-p" << new_resource.password if should_set?(:password) opts << "-s" << new_resource.shell if should_set?(:shell) opts << "-u" << new_resource.uid if should_set?(:uid) @@ -116,6 +134,12 @@ class Chef # FIXME: should probably go on the current_resource @locked end + + def prop_is_set?(prop) + v = new_resource.send(prop.to_sym) + + !v.nil? && v != "" + end end end end diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index d6c5fe7cdf..c9776fe346 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -660,8 +660,8 @@ class Chef text << "#{resource_name}(\"#{name}\") do\n" all_props = {} - self.class.state_properties.map do |p| + self.class.sensitive_properties.map do |p| all_props[p.name.to_s] = p.sensitive? ? '"*sensitive value suppressed*"' : value_to_text(p.get(self)) rescue Chef::Exceptions::ValidationFailed # This space left intentionally blank, the property was probably required or had an invalid default. diff --git a/lib/chef/resource/chef_client_cron.rb b/lib/chef/resource/chef_client_cron.rb index 26894c5ae3..b5014a368d 100644 --- a/lib/chef/resource/chef_client_cron.rb +++ b/lib/chef/resource/chef_client_cron.rb @@ -98,7 +98,7 @@ class Chef property :splay, [Integer, String], default: 300, coerce: proc { |x| Integer(x) }, - callbacks: { "should be a positive number" => proc { |v| v > 0 } }, + callbacks: { "should be a positive number" => proc { |v| v >= 0 } }, description: "A random number of seconds between 0 and X to add to interval so that all #{ChefUtils::Dist::Infra::CLIENT} commands don't execute at the same time." property :mailto, String, diff --git a/lib/chef/resource/chef_client_launchd.rb b/lib/chef/resource/chef_client_launchd.rb index 1016ea4d49..035f2353b7 100644 --- a/lib/chef/resource/chef_client_launchd.rb +++ b/lib/chef/resource/chef_client_launchd.rb @@ -60,7 +60,7 @@ class Chef property :splay, [Integer, String], default: 300, coerce: proc { |x| Integer(x) }, - callbacks: { "should be a positive number" => proc { |v| v > 0 } }, + callbacks: { "should be a positive number" => proc { |v| v >= 0 } }, description: "A random number of seconds between 0 and X to add to interval so that all #{ChefUtils::Dist::Infra::CLIENT} commands don't execute at the same time." property :accept_chef_license, [true, false], diff --git a/lib/chef/resource/chef_client_scheduled_task.rb b/lib/chef/resource/chef_client_scheduled_task.rb index a7e0d0761c..f04598cdc6 100644 --- a/lib/chef/resource/chef_client_scheduled_task.rb +++ b/lib/chef/resource/chef_client_scheduled_task.rb @@ -107,7 +107,7 @@ class Chef property :splay, [Integer, String], coerce: proc { |x| Integer(x) }, - callbacks: { "should be a positive number" => proc { |v| v > 0 } }, + callbacks: { "should be a positive number" => proc { |v| v >= 0 } }, description: "A random number of seconds between 0 and X to add to interval so that all #{ChefUtils::Dist::Infra::CLIENT} commands don't execute at the same time.", default: 300 @@ -122,7 +122,8 @@ class Chef property :config_directory, String, description: "The path of the config directory.", - default: ChefConfig::Config.etc_chef_dir + default: ChefConfig::Config.etc_chef_dir, + default_description: ChefConfig::Config.c_chef_dir property :log_directory, String, description: "The path of the directory to create the log file in.", diff --git a/lib/chef/resource/cron/cron_d.rb b/lib/chef/resource/cron/cron_d.rb index 9bd53d38b2..5aaf6fe954 100644 --- a/lib/chef/resource/cron/cron_d.rb +++ b/lib/chef/resource/cron/cron_d.rb @@ -145,6 +145,21 @@ class Chef new_resource.cron_name.tr(".", "-") end + def define_resource_requirements + requirements.assert(:create, :create_if_missing) do |a| + a.assertion do + # ensure valid cron job names for linux, otherwise the jobs won't be executed + if linux? + new_resource.cron_name =~ /^[a-zA-Z0-9_-]+$/ + else + true + end + end + a.failure_message("The cron job name should contain letters, numbers, hyphens and underscores only.") + a.block_action! + end + end + def create_template(create_action) # cleanup the legacy named job if it exists file "#{new_resource.cron_name} legacy named cron.d file" do diff --git a/lib/chef/resource/habitat/habitat_sup_windows.rb b/lib/chef/resource/habitat/habitat_sup_windows.rb index 1c574025d2..1757ea8e3b 100644 --- a/lib/chef/resource/habitat/habitat_sup_windows.rb +++ b/lib/chef/resource/habitat/habitat_sup_windows.rb @@ -15,7 +15,7 @@ # limitations under the License. # -require "win32/service" if RUBY_PLATFORM.match?(/mswin|mingw32|windows/) +require "win32/service" if RUBY_PLATFORM.match?(/mswin|mingw|windows/) require_relative "habitat_sup" class Chef diff --git a/lib/chef/resource/locale.rb b/lib/chef/resource/locale.rb index 8d9280b20b..a57dd70975 100644 --- a/lib/chef/resource/locale.rb +++ b/lib/chef/resource/locale.rb @@ -113,7 +113,7 @@ class Chef requirements.assert(:all_actions) do |a| # RHEL/CentOS type platforms don't have locale-gen - a.assertion { shell_out("locale-gen") } + a.assertion { which("locale-gen") } a.failure_message(Chef::Exceptions::ProviderNotFound, "The locale resource requires the locale-gen tool") end end diff --git a/lib/chef/resource/rhsm_register.rb b/lib/chef/resource/rhsm_register.rb index 53e1bc8daf..04c8f475bb 100644 --- a/lib/chef/resource/rhsm_register.rb +++ b/lib/chef/resource/rhsm_register.rb @@ -117,12 +117,17 @@ class Chef end end + package flush_package_cache_name do + action :nothing + end + execute "Register to RHSM" do sensitive new_resource.sensitive command register_command default_env true action :run not_if { registered_with_rhsm? } unless new_resource.force + notifies :flush_cache, "package[#{flush_package_cache_name}]", :immediately end if new_resource.install_katello_agent && !new_resource.satellite_host.nil? @@ -131,11 +136,16 @@ class Chef end action :unregister, description: "Unregister the node from RHSM." do + package flush_package_cache_name do + action :nothing + end + execute "Unregister from RHSM" do command "subscription-manager unregister" default_env true action :run only_if { registered_with_rhsm? } + notifies :flush_cache, "package[#{flush_package_cache_name}]", :immediately notifies :run, "execute[Clean RHSM Config]", :immediately end @@ -148,6 +158,13 @@ class Chef action_class do # + # @return [String] + # + def flush_package_cache_name + "rhsm_register-#{new_resource.name}-flush_cache" + end + + # # @return [Symbol] dnf_package or yum_package depending on OS release # def package_resource diff --git a/lib/chef/resource/selinux/common_helpers.rb b/lib/chef/resource/selinux/common_helpers.rb new file mode 100644 index 0000000000..a67943abad --- /dev/null +++ b/lib/chef/resource/selinux/common_helpers.rb @@ -0,0 +1,47 @@ +# +# 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. +# +class Chef + module SELinux + module CommonHelpers + def selinux_disabled? + selinux_state.eql?(:disabled) + end + + def selinux_enforcing? + selinux_state.eql?(:enforcing) + end + + def selinux_permissive? + selinux_state.eql?(:permissive) + end + + def state_change_reboot_required? + (selinux_disabled? && %i{enforcing permissive}.include?(action)) || ((selinux_enforcing? || selinux_permissive?) && action == :disabled) + end + + def selinux_state + state = shell_out!("getenforce").stdout.strip.downcase.to_sym + raise "Got unknown SELinux state #{state}" unless %i{disabled enforcing permissive}.include?(state) + + state + end + + def selinux_activate_required? + return false unless platform_family?("debian") + + !File.read("/etc/default/grub").match?("security=selinux") + end + end + end +end diff --git a/lib/chef/resource/selinux/selinux_debian.erb b/lib/chef/resource/selinux/selinux_debian.erb new file mode 100644 index 0000000000..07a11a0239 --- /dev/null +++ b/lib/chef/resource/selinux/selinux_debian.erb @@ -0,0 +1,18 @@ +# Generated by Chef for <%= node['fqdn'] %> +# Do NOT modify this file by hand. +# + +# This file controls the state of SELinux on the system. +# SELINUX= can take one of these three values: +# enforcing - SELinux security policy is enforced. +# permissive - SELinux prints warnings instead of enforcing. +# disabled - No SELinux policy is loaded. +SELINUX=<%= @selinux %> +# SELINUXTYPE= can take one of these three values: +# default - equivalent to the old strict and targeted policies +# mls - Multi-Level Security (for military and educational use) +# src - Custom policy built from source +SELINUXTYPE=<%= @selinuxtype %> + +# SETLOCALDEFS= Check local definition changes +SETLOCALDEFS=0
\ No newline at end of file diff --git a/lib/chef/resource/selinux/selinux_default.erb b/lib/chef/resource/selinux/selinux_default.erb new file mode 100644 index 0000000000..0fec407493 --- /dev/null +++ b/lib/chef/resource/selinux/selinux_default.erb @@ -0,0 +1,15 @@ +# Generated by Chef for <%= node['fqdn'] %> +# Do NOT modify this file by hand. +# + +# This file controls the state of SELinux on the system. +# SELINUX= can take one of these three values: +# enforcing - SELinux security policy is enforced. +# permissive - SELinux prints warnings instead of enforcing. +# disabled - No SELinux policy is loaded. +SELINUX=<%= @selinux %> +# SELINUXTYPE= can take one of these three values: +# targeted - Targeted processes are protected, +# minimum - Modification of targeted policy. Only selected processes are protected. +# mls - Multi Level Security protection. +SELINUXTYPE=<%= @selinuxtype %>
\ No newline at end of file diff --git a/lib/chef/resource/selinux_boolean.rb b/lib/chef/resource/selinux_boolean.rb new file mode 100644 index 0000000000..919c1d274a --- /dev/null +++ b/lib/chef/resource/selinux_boolean.rb @@ -0,0 +1,101 @@ +# +# 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_relative "../resource" +require_relative "selinux/common_helpers" + +class Chef + class Resource + class SelinuxBoolean < Chef::Resource + unified_mode true + + provides :selinux_boolean + + description "Use **selinux_boolean** resource to set SELinux boolean values." + introduced "18.0" + examples <<~DOC + **Set ssh_keysign to true**: + + ```ruby + selinux_boolean 'ssh_keysign' do + value true + end + ``` + + **Set ssh_sysadm_login to 'on'**: + + ```ruby + selinux_boolean 'ssh_sysadm_login' do + value 'on' + end + ``` + DOC + + property :boolean, String, + name_property: true, + description: "SELinux boolean to set." + + property :value, [Integer, String, true, false], + required: true, + equal_to: %w{on off}, + coerce: proc { |p| selinux_bool(p) }, + description: "SELinux boolean value." + + property :persistent, [true, false], + default: true, + desired_state: false, + description: "Set to true for value setting to survive reboot." + + load_current_value do |new_resource| + value shell_out!("getsebool", new_resource.boolean).stdout.split("-->").map(&:strip).last + end + + action_class do + include Chef::SELinux::CommonHelpers + end + + action :set , description: "Set the state of the boolean." do + if selinux_disabled? + Chef::Log.warn("Unable to set SELinux boolean #{new_resource.name} as SELinux is disabled") + return + end + + converge_if_changed do + cmd = "setsebool" + cmd += " -P" if new_resource.persistent + cmd += " #{new_resource.boolean} #{new_resource.value}" + + shell_out!(cmd) + end + end + + private + + # + # Validate and return input boolean value in required format + # @param bool [String, Integer, Boolean] Input boolean value in allowed formats + # + # @return [String] [description] Boolean value in required format + def selinux_bool(bool) + if ["on", "true", "1", true, 1].include?(bool) + "on" + elsif ["off", "false", "0", false, 0].include?(bool) + "off" + else + raise ArgumentError, "selinux_bool: Invalid selinux boolean value #{bool}" + end + end + end + end +end diff --git a/lib/chef/resource/selinux_fcontext.rb b/lib/chef/resource/selinux_fcontext.rb new file mode 100644 index 0000000000..243b180f3c --- /dev/null +++ b/lib/chef/resource/selinux_fcontext.rb @@ -0,0 +1,160 @@ +# +# 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_relative "../resource" +require_relative "selinux/common_helpers" + +class Chef + class Resource + class SelinuxFcontext < Chef::Resource + unified_mode true + + provides :selinux_fcontext + + description "Use **selinux_fcontext** resource to set the SELinux context of files with semanage fcontext." + introduced "18.0" + examples <<~DOC + **Allow http servers (e.g. nginx/apache) to modify moodle files**: + + ```ruby + selinux_fcontext '/var/www/moodle(/.*)?' do + secontext 'httpd_sys_rw_content_t' + end + ``` + + **Adapt a symbolic link**: + + ```ruby + selinux_fcontext '/var/www/symlink_to_webroot' do + secontext 'httpd_sys_rw_content_t' + file_type 'l' + end + ``` + DOC + + property :file_spec, String, + name_property: true, + description: "Path to or regex matching the files or directories to label." + + property :secontext, String, + required: %i{add modify manage}, + description: "SELinux context to assign." + + property :file_type, String, + default: "a", + equal_to: %w{a f d c b s l p}, + description: "The type of the file being labeled." + + action_class do + include Chef::SELinux::CommonHelpers + def current_file_context + file_hash = { + "a" => "all files", + "f" => "regular file", + "d" => "directory", + "c" => "character device", + "b" => "block device", + "s" => "socket", + "l" => "symbolic link", + "p" => "named pipe", + } + + contexts = shell_out!("semanage fcontext -l").stdout.split("\n") + # pull out file label from user:role:type:level context string + contexts.grep(/^#{Regexp.escape(new_resource.file_spec)}\s+#{file_hash[new_resource.file_type]}/) do |c| + c.match(/.+ (?<user>.+):(?<role>.+):(?<type>.+):(?<level>.+)$/)[:type] + # match returns ['foo'] or [], shift converts that to 'foo' or nil + end.shift + end + + # Run restorecon to fix label + # https://github.com/sous-chefs/selinux_policy/pull/72#issuecomment-338718721 + def relabel_files + spec = new_resource.file_spec + escaped = Regexp.escape spec + + # find common path between regex and string + common = if spec == escaped + spec + else + index = spec.size.times { |i| break i if spec[i] != escaped[i] } + ::File.dirname spec[0...index] + end + + # if path is not absolute, ignore it and search everything + common = "/" if common[0] != "/" + + if ::File.exist? common + shell_out!("find #{common.shellescape} -ignore_readdir_race -regextype posix-egrep -regex #{spec.shellescape} -prune -print0 | xargs -0 restorecon -iRv") + end + end + end + + action :manage, description: "Assign the file to the right context regardless of previous state." do + run_action(:add) + run_action(:modify) + end + + action :addormodify, description: "Assign the file context if not set. Update the file context if previously set." do + Chef::Log.warn("The :addormodify action for selinux_fcontext is deprecated and will be removed in a future release. Use the :manage action instead.") + run_action(:manage) + end + + # Create if doesn't exist, do not touch if fcontext is already registered + action :add, description: "Assign the file context if not set." do + if selinux_disabled? + Chef::Log.warn("Unable to add SELinux fcontext #{new_resource.name} as SELinux is disabled") + return + end + + unless current_file_context + converge_by "adding label #{new_resource.secontext} to #{new_resource.file_spec}" do + shell_out!("semanage fcontext -a -f #{new_resource.file_type} -t #{new_resource.secontext} '#{new_resource.file_spec}'") + relabel_files + end + end + end + + # Only modify if fcontext exists & doesn't have the correct label already + action :modify, description: "Update the file context if previously set." do + if selinux_disabled? + Chef::Log.warn("Unable to modify SELinux fcontext #{new_resource.name} as SELinux is disabled") + return + end + + if current_file_context && current_file_context != new_resource.secontext + converge_by "modifying label #{new_resource.secontext} to #{new_resource.file_spec}" do + shell_out!("semanage fcontext -m -f #{new_resource.file_type} -t #{new_resource.secontext} '#{new_resource.file_spec}'") + relabel_files + end + end + end + + # Delete if exists + action :delete, description: "Removes the file context if set. " do + if selinux_disabled? + Chef::Log.warn("Unable to delete SELinux fcontext #{new_resource.name} as SELinux is disabled") + return + end + + if current_file_context + converge_by "deleting label for #{new_resource.file_spec}" do + shell_out!("semanage fcontext -d -f #{new_resource.file_type} '#{new_resource.file_spec}'") + relabel_files + end + end + end + end + end +end
\ No newline at end of file diff --git a/lib/chef/resource/selinux_install.rb b/lib/chef/resource/selinux_install.rb new file mode 100644 index 0000000000..d53a74392a --- /dev/null +++ b/lib/chef/resource/selinux_install.rb @@ -0,0 +1,107 @@ +# +# 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_relative "../resource" + +class Chef + class Resource + class SelinuxInstall < Chef::Resource + unified_mode true + + provides :selinux_install + + description "Use **selinux_install** resource to encapsulates the set of selinux packages to install in order to manage selinux. It also ensures the directory `/etc/selinux` is created." + introduced "18.0" + examples <<~DOC + **Default installation**: + + ```ruby + selinux_install 'example' + ``` + + **Install with custom packages**: + + ```ruby + selinux_install 'example' do + packages %w(policycoreutils selinux-policy selinux-policy-targeted) + end + ``` + + **Uninstall** + ```ruby + selinux_install 'example' do + action :remove + end + ``` + DOC + + property :packages, [String, Array], + default: lazy { default_install_packages }, + description: "SELinux packages for system." + + action_class do + def do_package_action(action) + # friendly message for unsupported platforms + raise "The platform #{node["platform"]} is not currently supported by the `selinux_install` resource. Please file an issue at https://github.com/chef/chef/issues with details on the platform this cookbook is running on." if new_resource.packages.nil? + + package "selinux" do + package_name new_resource.packages + action action + end + end + end + + action :install, description: "Install required packages." do + do_package_action(action) + + directory "/etc/selinux" do + owner "root" + group "root" + mode "0755" + action :create + end + end + + action :upgrade, description: "Upgrade required packages." do + do_package_action(a) + end + + action :remove, description: "Remove any SELinux-related packages." do + do_package_action(a) + end + + private + + # + # Get an array of packages to be installed based upon node platform_family + # + # @return [Array] Array of string of package names + def default_install_packages + case node["platform_family"] + when "rhel", "fedora", "amazon" + %w{make policycoreutils selinux-policy selinux-policy-targeted selinux-policy-devel libselinux-utils setools-console} + when "debian" + if node["platform"] == "ubuntu" + if node["platform_version"].to_f == 18.04 + %w{make policycoreutils selinux selinux-basics selinux-policy-default selinux-policy-dev auditd setools} + else + %w{make policycoreutils selinux-basics selinux-policy-default selinux-policy-dev auditd setools} + end + else + %w{make policycoreutils selinux-basics selinux-policy-default selinux-policy-dev auditd setools} + end + end + end + end + end +end diff --git a/lib/chef/resource/selinux_module.rb b/lib/chef/resource/selinux_module.rb new file mode 100644 index 0000000000..49810e4b23 --- /dev/null +++ b/lib/chef/resource/selinux_module.rb @@ -0,0 +1,143 @@ +# +# 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_relative "../resource" + +class Chef + class Resource + class SelinuxModule < Chef::Resource + unified_mode true + + provides :selinux_module + + description "Use **selinux_module** module resource to create an SELinux policy module from a cookbook file or content provided as a string." + introduced "18.0" + examples <<~DOC + **Creating SElinux module from .te file located at `files` directory of your cookbook.**: + + ```ruby + selinux_module 'my_policy_module' do + source 'my_policy_module.te' + action :create + end + ``` + DOC + + property :module_name, String, + name_property: true, + description: "Override the module name." + + property :source, String, + description: "Module source file name." + + property :content, String, + description: "Module source as String." + + property :cookbook, String, + description: "Cookbook to source from module source file from(if it is not located in the current cookbook). The default value is the current cookbook.", + desired_state: false + + property :base_dir, String, + default: "/etc/selinux/local", + description: "Directory to create module source file in." + + action_class do + def selinux_module_filepath(type) + path = ::File.join(new_resource.base_dir, "#{new_resource.module_name}") + path.concat(".#{type}") if type + end + + def list_installed_modules + shell_out!("semodule --list-modules").stdout.split("\n").map { |x| x.split(/\s/).first } + end + end + + action :create, description: "Compile a module and install it." do + directory new_resource.base_dir + + if property_is_set?(:content) + file selinux_module_filepath("te") do + content new_resource.content + + mode "0600" + owner "root" + group "root" + + action :create + + notifies :run, "execute[Compiling SELinux modules at '#{new_resource.base_dir}']", :immediately + end + else + cookbook_file selinux_module_filepath("te") do + cookbook new_resource.cookbook + source new_resource.source + + mode "0600" + owner "root" + group "root" + + action :create + + notifies :run, "execute[Compiling SELinux modules at '#{new_resource.base_dir}']", :immediately + end + end + + execute "Compiling SELinux modules at '#{new_resource.base_dir}'" do + cwd new_resource.base_dir + command "make -C #{new_resource.base_dir} -f /usr/share/selinux/devel/Makefile" + timeout 120 + user "root" + + action :nothing + + notifies :run, "execute[Install SELinux module '#{selinux_module_filepath("pp")}']", :immediately + end + + raise "Compilation must have failed, no 'pp' file found at: '#{selinux_module_filepath("pp")}'" unless ::File.exist?(selinux_module_filepath("pp")) + + execute "Install SELinux module '#{selinux_module_filepath("pp")}'" do + command "semodule --install '#{selinux_module_filepath("pp")}'" + action :nothing + end + end + + action :delete, description: "Remove module source files from `/etc/selinux/local`." do + %w{fc if pp te}.each do |type| + next unless ::File.exist?(selinux_module_filepath(type)) + + file selinux_module_filepath(type) do + action :delete + end + end + end + + action :install, description: "Install a compiled module into the system." do + raise "Module must be compiled before it can be installed, no 'pp' file found at: '#{selinux_module_filepath("pp")}'" unless ::File.exist?(selinux_module_filepath("pp")) + + unless list_installed_modules.include? new_resource.module_name + converge_by "Install SELinux module #{selinux_module_filepath("pp")}" do + shell_out!("semodule", "--install", selinux_module_filepath("pp")) + end + end + end + + action :remove, description: "Remove a module from the system." do + if list_installed_modules.include? new_resource.module_name + converge_by "Remove SELinux module #{new_resource.module_name}" do + shell_out!("semodule", "--remove", new_resource.module_name) + end + end + end + end + end +end
\ No newline at end of file diff --git a/lib/chef/resource/selinux_permissive.rb b/lib/chef/resource/selinux_permissive.rb new file mode 100644 index 0000000000..155f4ef390 --- /dev/null +++ b/lib/chef/resource/selinux_permissive.rb @@ -0,0 +1,64 @@ +# +# 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_relative "../resource" + +class Chef + class Resource + class SelinuxPermissive < Chef::Resource + unified_mode true + + provides :selinux_permissive + + description "Use **selinux_permissive** resource to allows some types to misbehave without stopping them. Not as good as specific policies, but better than disabling SELinux entirely." + introduced "18.0" + examples <<~DOC + **Disable enforcement on Apache**: + + ```ruby + selinux_permissive 'httpd_t' do + notifies :restart, 'service[httpd]' + end + ``` + DOC + + property :context, String, + name_property: true, + description: "The SELinux context to permit." + + action_class do + def current_permissives + shell_out!("semanage permissive -ln").stdout.split("\n") + end + end + + # Create if doesn't exist, do not touch if permissive is already registered (even under different type) + action :add, description: "Add a permissive, unless already set." do + unless current_permissives.include? new_resource.context + converge_by "adding permissive context #{new_resource.context}" do + shell_out!("semanage permissive -a '#{new_resource.context}'") + end + end + end + + # Delete if exists + action :delete, description: "Remove a permissive, if set." do + if current_permissives.include? new_resource.context + converge_by "deleting permissive context #{new_resource.context}" do + shell_out!("semanage permissive -d '#{new_resource.context}'") + end + end + end + end + end +end
\ No newline at end of file diff --git a/lib/chef/resource/selinux_port.rb b/lib/chef/resource/selinux_port.rb new file mode 100644 index 0000000000..8690adf9b1 --- /dev/null +++ b/lib/chef/resource/selinux_port.rb @@ -0,0 +1,118 @@ +# +# 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_relative "../resource" +require_relative "selinux/common_helpers" + +class Chef + class Resource + class SelinuxPort < Chef::Resource + unified_mode true + + provides :selinux_port + + description "Use **selinux_port** resource to allows assigning a network port to a certain SELinux context, e.g. for running a webserver on a non-standard port." + introduced "18.0" + examples <<~DOC + **Allow nginx/apache to bind to port 5678 by giving it the http_port_t context**: + + ```ruby + selinux_port '5678' do + protocol 'tcp' + secontext 'http_port_t' + end + ``` + DOC + + property :port, [Integer, String], + name_property: true, + regex: /^\d+$/, + description: "Port to modify." + + property :protocol, String, + equal_to: %w{tcp udp}, + required: %i{manage add modify}, + description: "Protocol to modify." + + property :secontext, String, + required: %i{manage add modify}, + description: "SELinux context to assign to the port." + + action_class do + include Chef::SELinux::CommonHelpers + def current_port_context + # use awk to see if the given port is within a reported port range + shell_out!( + <<~CMD + seinfo --portcon=#{new_resource.port} | grep 'portcon #{new_resource.protocol}' | \ + awk -F: '$(NF-1) !~ /reserved_port_t$/ && $(NF-3) !~ /[0-9]*-[0-9]*/ {print $(NF-1)}' + CMD + ).stdout.split + end + end + + action :manage, description: "Assign the port to the right context regardless of previous state." do + run_action(:add) + run_action(:modify) + end + + action :addormodify, description: "Assigns the port context if not set. Updates the port context if previously set." do + Chef::Log.warn("The :addormodify action for selinux_port is deprecated and will be removed in a future release. Use the :manage action instead.") + run_action(:manage) + end + + # Create if doesn't exist, do not touch if port is already registered (even under different type) + action :add, description: "Assign the port context if not set." do + if selinux_disabled? + Chef::Log.warn("Unable to add SELinux port #{new_resource.name} as SELinux is disabled") + return + end + + if current_port_context.empty? + converge_by "Adding context #{new_resource.secontext} to port #{new_resource.port}/#{new_resource.protocol}" do + shell_out!("semanage port -a -t '#{new_resource.secontext}' -p #{new_resource.protocol} #{new_resource.port}") + end + end + end + + # Only modify port if it exists & doesn't have the correct context already + action :modify, description: "Update the port context if previously set." do + if selinux_disabled? + Chef::Log.warn("Unable to modify SELinux port #{new_resource.name} as SELinux is disabled") + return + end + + if !current_port_context.empty? && !current_port_context.include?(new_resource.secontext) + converge_by "Modifying context #{new_resource.secontext} to port #{new_resource.port}/#{new_resource.protocol}" do + shell_out!("semanage port -m -t '#{new_resource.secontext}' -p #{new_resource.protocol} #{new_resource.port}") + end + end + end + + # Delete if exists + action :delete, description: "Removes the port context if set." do + if selinux_disabled? + Chef::Log.warn("Unable to delete SELinux port #{new_resource.name} as SELinux is disabled") + return + end + + unless current_port_context.empty? + converge_by "Deleting context from port #{new_resource.port}/#{new_resource.protocol}" do + shell_out!("semanage port -d -p #{new_resource.protocol} #{new_resource.port}") + end + end + end + + end + end +end
\ No newline at end of file diff --git a/lib/chef/resource/selinux_state.rb b/lib/chef/resource/selinux_state.rb new file mode 100644 index 0000000000..095a272ef7 --- /dev/null +++ b/lib/chef/resource/selinux_state.rb @@ -0,0 +1,166 @@ +# +# 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_relative "../resource" +require_relative "selinux/common_helpers" + +class Chef + class Resource + class SelinuxState < Chef::Resource + unified_mode true + + provides :selinux_state + + description "Use **selinux_state** resource to manages the SELinux state on the system. It does this by using the `setenforce` command and rendering the `/etc/selinux/config` file from a template." + introduced "18.0" + examples <<~DOC + **Set SELinux state to permissive**: + + ```ruby + selinux_state 'permissive' do + action :permissive + end + ``` + + **Set SELinux state to enforcing**: + + ```ruby + selinux_state 'enforcing' do + action :enforcing + end + ``` + + **Set SELinux state to disabled**: + ```ruby + selinux_state 'disabled' do + action :disabled + end + ``` + DOC + + default_action :nothing + + property :config_file, String, + default: "/etc/selinux/config", + description: "Path to SELinux config file on disk." + + property :persistent, [true, false], + default: true, + description: "Persist status update to the selinux configuration file." + + property :policy, String, + default: lazy { default_policy_platform }, + equal_to: %w{default minimum mls src strict targeted}, + description: "SELinux policy type." + + property :automatic_reboot, [true, false, Symbol], + default: false, + description: "Perform an automatic node reboot if required for state change." + + deprecated_property_alias "temporary", "persistent", "The temporary property was renamed persistent in the 4.0 release of this cookbook. Please update your cookbooks to use the new property name." + + action_class do + include Chef::SELinux::CommonHelpers + def render_selinux_template(action) + Chef::Log.warn("It is advised to set the configuration first to permissive to relabel the filesystem prior to enforcing.") if selinux_disabled? && action == :enforcing + + unless new_resource.automatic_reboot + Chef::Log.warn("Changes from disabled require a reboot.") if selinux_disabled? && %i{enforcing permissive}.include?(action) + Chef::Log.warn("Disabling selinux requires a reboot.") if (selinux_enforcing? || selinux_permissive?) && action == :disabled + end + + template "#{action} selinux config" do + path new_resource.config_file + source debian? ? ::File.expand_path("selinux/selinux_debian.erb", __dir__) : ::File.expand_path("selinux/selinux_default.erb", __dir__) + local true + variables( + selinux: action.to_s, + selinuxtype: new_resource.policy + ) + end + end + + def node_selinux_restart + unless new_resource.automatic_reboot + Chef::Log.warn("SELinux state change to #{action} requires a manual reboot as SELinux is currently #{selinux_state} and automatic reboots are disabled.") + return + end + + outer_action = action + reboot "selinux_state_change" do + delay_mins 1 + reason "SELinux state change to #{outer_action} from #{selinux_state}" + + action new_resource.automatic_reboot.is_a?(Symbol) ? new_resource.automatic_reboot : :reboot_now + end + end + end + + action :enforcing, description: "Set the SELinux state to enforcing." do + unless selinux_disabled? || selinux_enforcing? + execute "selinux-setenforce-enforcing" do + command "/usr/sbin/setenforce 1" + end + end + + if selinux_activate_required? + execute "debian-selinux-activate" do + command "/usr/sbin/selinux-activate" + end + end + + render_selinux_template(action) if new_resource.persistent + node_selinux_restart if state_change_reboot_required? + end + + action :permissive, description: "Set the SELinux state to permissive." do + unless selinux_disabled? || selinux_permissive? + execute "selinux-setenforce-permissive" do + command "/usr/sbin/setenforce 0" + end + end + + if selinux_activate_required? + execute "debian-selinux-activate" do + command "/usr/sbin/selinux-activate" + end + end + + render_selinux_template(action) if new_resource.persistent + node_selinux_restart if state_change_reboot_required? + end + + action :disabled, description: "Set the SELinux state to disabled. **NOTE**: Switching to or from disabled requires a reboot!" do + raise "A non-persistent change to the disabled SELinux status is not possible." unless new_resource.persistent + + render_selinux_template(action) + node_selinux_restart if state_change_reboot_required? + end + + private + + # + # Decide default policy platform based upon platform_family + # + # @return [String] Policy platform name + def default_policy_platform + case node["platform_family"] + when "rhel", "fedora", "amazon" + "targeted" + when "debian" + "default" + end + end + end + end +end
\ No newline at end of file diff --git a/lib/chef/resource/support/client.erb b/lib/chef/resource/support/client.erb index 724adc9325..45f98ab8c0 100644 --- a/lib/chef/resource/support/client.erb +++ b/lib/chef/resource/support/client.erb @@ -13,8 +13,6 @@ @minimal_ohai @named_run_list @no_proxy - @ohai_disabled_plugins - @ohai_optional_plugins @pid_file @policy_group @policy_name @@ -40,10 +38,10 @@ log_location <%= @log_location.inspect %> <% end -%> <%# These data_collector options are special as they have a '.' -%> <% unless @data_collector_server_url.nil? || @data_collector_server_url.empty? %> -data_collector.server_url <%= @data_collector_server_url %> +data_collector.server_url <%= @data_collector_server_url.inspect %> <% end %> <% unless @data_collector_token.nil? || @data_collector_token.empty? %> -data_collector.token <%= @data_collector_token %> +data_collector.token <%= @data_collector_token.inspect %> <% end %> <%# The code below is not DRY on purpose to improve readability -%> <% unless @start_handlers.empty? -%> diff --git a/lib/chef/resource/sysctl.rb b/lib/chef/resource/sysctl.rb index 97f919fbc9..61f3686ccc 100644 --- a/lib/chef/resource/sysctl.rb +++ b/lib/chef/resource/sysctl.rb @@ -187,7 +187,7 @@ class Chef sysctl_lines << "#{new_resource.key} = #{new_resource.value}" - sysctl_lines.join("\n") + sysctl_lines.join("\n") + "\n" end end diff --git a/lib/chef/resource/user.rb b/lib/chef/resource/user.rb index 992935a6b6..0e84a6b645 100644 --- a/lib/chef/resource/user.rb +++ b/lib/chef/resource/user.rb @@ -72,6 +72,16 @@ class Chef description: "The numeric group identifier." alias_method :group, :gid + + property :expire_date, [ String, NilClass ], + description: "(Linux) The date on which the user account will be disabled. The date is specified in the format YYYY-MM-DD.", + introduced: "18.0", + desired_state: false + + property :inactive, [ String, Integer, NilClass ], + description: "(Linux) The number of days after a password expires until the account is permanently disabled. A value of 0 disables the account as soon as the password has expired, and a value of -1 disables the feature.", + introduced: "18.0", + desired_state: false end end end diff --git a/lib/chef/resource/windows_certificate.rb b/lib/chef/resource/windows_certificate.rb index 3fcaec0948..79abfa4c19 100644 --- a/lib/chef/resource/windows_certificate.rb +++ b/lib/chef/resource/windows_certificate.rb @@ -128,14 +128,14 @@ class Chef end action :delete, description: "Deletes a certificate." do - cert_obj = fetch_cert + cert_is_valid = verify_cert - if cert_obj + if cert_is_valid == true converge_by("Deleting certificate #{new_resource.source} from Store #{new_resource.store_name}") do delete_cert end else - Chef::Log.debug("Certificate not found") + Chef::Log.debug("Certificate Not Found") end end @@ -145,17 +145,25 @@ class Chef end if ::File.extname(new_resource.output_path) == ".pfx" - powershell_exec!(pfx_ps_cmd(resolve_thumbprint(new_resource.source), store_location: ps_cert_location, store_name: new_resource.store_name, output_path: new_resource.output_path, password: new_resource.pfx_password )) + + validated_thumbprint = validate_thumbprint(new_resource.source) + if validated_thumbprint != false # is the thumbprint valid + cert_obj = powershell_exec!(pfx_ps_cmd(validate_thumbprint(new_resource.source), store_location: ps_cert_location, store_name: new_resource.store_name, output_path: new_resource.output_path, password: new_resource.pfx_password )) + else + message = "While fetching the certificate, was passed the following invalid certificate thumbprint : #{new_resource.source}\n" + raise Chef::Exceptions::InvalidKeyAttribute, message + end + else cert_obj = fetch_cert end - if cert_obj + if cert_obj != false && cert_obj != "Certificate Not Found" converge_by("Fetching certificate #{new_resource.source} from Store \\#{ps_cert_location}\\#{new_resource.store_name}") do export_cert(cert_obj, output_path: new_resource.output_path, store_name: new_resource.store_name , store_location: ps_cert_location, pfx_password: new_resource.pfx_password) end else - Chef::Log.debug("Certificate not found") + Chef::Log.debug("Certificate Not Found") end end @@ -186,7 +194,7 @@ class Chef def delete_cert store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location) - store.delete(resolve_thumbprint(new_resource.source)) + store.delete(validate_thumbprint(new_resource.source)) end def fetch_cert @@ -195,17 +203,16 @@ class Chef fetch_key else - store.get(resolve_thumbprint(new_resource.source), store_name: new_resource.store_name, store_location: native_cert_location) + store.get(validate_thumbprint(new_resource.source)) end end def fetch_key require "openssl" unless defined?(OpenSSL) file_name = ::File.basename(new_resource.output_path, ::File.extname(new_resource.output_path)) - directory = ::File.dirname(new_resource.output_path) pfx_file = file_name + ".pfx" new_pfx_output_path = ::File.join(Chef::FileCache.create_cache_path("pfx_files"), pfx_file) - powershell_exec(pfx_ps_cmd(resolve_thumbprint(new_resource.source), store_location: ps_cert_location, store_name: new_resource.store_name, output_path: new_pfx_output_path, password: new_resource.pfx_password )) + powershell_exec(pfx_ps_cmd(validate_thumbprint(new_resource.source), store_location: ps_cert_location, store_name: new_resource.store_name, output_path: new_pfx_output_path, password: new_resource.pfx_password )) pkcs12 = OpenSSL::PKCS12.new(::File.binread(new_pfx_output_path), new_resource.pfx_password) f = ::File.open(new_resource.output_path, "w") f.write(pkcs12.key.to_s) @@ -244,10 +251,6 @@ class Chef ::File.file?(source) end - def is_file?(source) - ::File.file?(source) - end - # Thumbprints should be exactly 40 Hex characters def valid_thumbprint?(string) string.match?(/[0-9A-Fa-f]/) && string.length == 40 @@ -260,29 +263,29 @@ class Chef GETTHUMBPRINTCODE end - def resolve_thumbprint(thumbprint) - return thumbprint if valid_thumbprint?(thumbprint) - - powershell_exec!(get_thumbprint(new_resource.store_name, ps_cert_location, new_resource.source)).result + def validate_thumbprint(thumbprint) + # valid_thumbprint can return false under at least 2 conditions: + # one is that the thumbprint is in fact busted + # the second is that the thumbprint is valid but belongs to an expired certificate already installed + results = valid_thumbprint?(thumbprint) + results == true ? thumbprint : false end - # Checks whether a certificate with the given thumbprint - # is already present and valid in certificate store - # If the certificate is not present, verify_cert returns a String: "Certificate not found" - # But if it is present but expired, it returns a Boolean: false - # Otherwise, it returns a Boolean: true - # updated this method to accept either a subject name or a thumbprint - 1/29/2021 - + # Checks to make sure whether the cert is found or not + # if it IS found, is it still valid - has it expired? def verify_cert(thumbprint = new_resource.source) store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location) - if new_resource.pfx_password.nil? - store.valid?(resolve_thumbprint(thumbprint), store_location: native_cert_location, store_name: new_resource.store_name ) + validated_thumbprint = validate_thumbprint(thumbprint) + if validated_thumbprint != false + result = store.valid?(thumbprint) + result == ( "Certificate Not Found" || "Certificate Has Expired" ) ? false : true else - store.valid?(resolve_thumbprint(thumbprint), store_location: native_cert_location, store_name: new_resource.store_name) + message = "While verifying the certificate, was passed the following invalid certificate thumbprint : #{thumbprint}\n" + raise Chef::Exceptions::InvalidKeyAttribute, message end end - # this array structure is solving 2 problems. The first is that we need to have support for both the CurrentUser AND LocalMachine stores + # this structure is solving 2 problems. The first is that we need to have support for both the CurrentUser AND LocalMachine stores # Secondly, we need to pass the proper constant name for each store to win32-certstore but also pass the short name to powershell scripts used here def ps_cert_location new_resource.user_store ? "CurrentUser" : "LocalMachine" @@ -435,7 +438,7 @@ class Chef end def export_cert(cert_obj, output_path:, store_name:, store_location:, pfx_password:) - # Delete the cert if it exists. This is non-destructive in that it only removes the file and not the entire path. + # Delete the cert if it exists on disk already. # We want to ensure we're not randomly loading an old stinky cert. if ::File.exists?(output_path) ::File.delete(output_path) @@ -459,7 +462,20 @@ class Chef cert_out = shell_out("openssl x509 -text -inform DER -in #{cert_obj} -outform CRT").stdout out_file.puts(cert_out) when ".pfx" - pfx_ps_cmd(resolve_thumbprint(new_resource.source), store_location: store_location, store_name: store_name, output_path: output_path, password: pfx_password ) + validated_thumbprint = validate_thumbprint(new_resource.source) + if validated_thumbprint != false # is the thumbprint valid + store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location) + result = store.valid?(new_resource.source) # is there a cert in the store matching that thumbprint + temp = result == ( "Certificate Not Found" || "Certificate Has Expired" ) ? false : true + if temp == true + pfx_ps_cmd(validate_thumbprint(new_resource.source), store_location: store_location, store_name: store_name, output_path: output_path, password: pfx_password ) + else + Chef::Log.debug("The requested certificate is not found or has expired") + end + else + message = "While exporting the pfx, was passed the following invalid certificate thumbprint : #{new_resource.source}\n" + raise Chef::Exceptions::InvalidKeyAttribute, message + end when ".p7b" cert_out = shell_out("openssl pkcs7 -export -nokeys -in #{cert_obj.to_pem} -outform P7B").stdout out_file.puts(cert_out) @@ -480,14 +496,11 @@ class Chef # def import_certificates(cert_objs, is_pfx, store_name: new_resource.store_name, store_location: native_cert_location) [cert_objs].flatten.each do |cert_obj| - # thumbprint = OpenSSL::Digest.new("SHA1", cert_obj.to_der).to_s - # pkcs = OpenSSL::PKCS12.new(cert_obj, new_resource.pfx_password) - # cert = OpenSSL::X509::Certificate.new(pkcs.certificate.to_pem) thumbprint = OpenSSL::Digest.new("SHA1", cert_obj.to_der).to_s - if is_pfx - if verify_cert(thumbprint) == true - Chef::Log.debug("Certificate is already present") - else + if verify_cert(thumbprint) == true + Chef::Log.debug("Certificate is already present") + elsif verify_cert(thumbprint) == false # Not found already in the CertStore + if is_pfx if is_file?(new_resource.source) converge_by("Creating a PFX #{new_resource.source} for Store #{new_resource.store_name}") do add_pfx_cert(new_resource.source) @@ -501,15 +514,14 @@ class Chef message << exception.message raise Chef::Exceptions::ArgumentError, message end - end - else - if verify_cert(thumbprint) == true - Chef::Log.debug("Certificate is already present") else converge_by("Creating a certificate #{new_resource.source} for Store #{new_resource.store_name}") do add_cert(cert_obj) end end + else + message = "Certificate could not be imported" + raise Chef::Exceptions::CertificateNotImportable, message end end end diff --git a/lib/chef/resource/windows_pagefile.rb b/lib/chef/resource/windows_pagefile.rb index 03649e28aa..543170a70e 100644 --- a/lib/chef/resource/windows_pagefile.rb +++ b/lib/chef/resource/windows_pagefile.rb @@ -87,7 +87,7 @@ class Chef if automatic_managed set_automatic_managed unless automatic_managed? elsif automatic_managed == false - unset_automatic_managed if automatic_managed? + unset_automatic_managed else pagefile = clarify_pagefile_name initial_size = new_resource.initial_size @@ -148,10 +148,12 @@ class Chef def exists?(pagefile) @exists ||= begin logger.trace("Checking if #{pagefile} exists by running: Get-CimInstance Win32_PagefileSetting | Where-Object { $_.name -eq $($pagefile)} ") - cmd = "$page_file_name = '#{pagefile}';" - cmd << "$pagefile = Get-CimInstance Win32_PagefileSetting | Where-Object { $_.name -eq $($page_file_name)};" - cmd << "if ([string]::IsNullOrEmpty($pagefile)) { return $false } else { return $true }" - powershell_exec!(cmd).result + powershell_code = <<~CODE + $page_file_name = '#{pagefile}'; + $pagefile = Get-CimInstance Win32_PagefileSetting | Where-Object { $_.name -eq $($page_file_name)} + if ([string]::IsNullOrEmpty($pagefile)) { return $false } else { return $true } + CODE + powershell_exec!(powershell_code).result end end @@ -163,13 +165,16 @@ class Chef # @return [Boolean] def max_and_min_set?(pagefile, min, max) logger.trace("Checking if #{pagefile} has max and initial disk size values set") - cmd = "$page_file = '#{pagefile}';" - cmd << "$driveLetter = $page_file.split(':')[0];" - cmd << "$page_file_settings = Get-CimInstance -ClassName Win32_PageFileSetting -Filter \"SettingID='pagefile.sys @ $($driveLetter):'\" -Property * -ErrorAction Stop;" - cmd << "if ($page_file_settings.InitialSize -eq #{min} -and $page_file_settings.MaximumSize -eq #{max})" - cmd << "{ return $true }" - cmd << "else { return $false }" - powershell_exec!(cmd).result + powershell_code = <<-CODE + $page_file = '#{pagefile}'; + $driveLetter = $page_file.split(':')[0]; + $page_file_settings = Get-CimInstance -ClassName Win32_PageFileSetting -Filter "SettingID='pagefile.sys @ $($driveLetter):'" -Property * -ErrorAction Stop; + if ($page_file_settings.InitialSize -eq #{min} -and $page_file_settings.MaximumSize -eq #{max}) + { return $true } + else + { return $false } + CODE + powershell_exec!(powershell_code).result end # create a pagefile @@ -224,12 +229,14 @@ class Chef # turn off automatic management of all pagefiles by Windows def unset_automatic_managed - converge_by("Turn off Automatically Managed on pagefiles") do - logger.trace("Running Set-CimInstance -InputObject $sys -Property @{AutomaticManagedPagefile=$false} -PassThru") - powershell_exec! <<~EOH - $sys = Get-CimInstance Win32_ComputerSystem -Property * - Set-CimInstance -InputObject $sys -Property @{AutomaticManagedPagefile=$false} -PassThru - EOH + if automatic_managed? + converge_by("Turn off Automatically Managed on pagefiles") do + logger.trace("Running Set-CimInstance -InputObject $sys -Property @{AutomaticManagedPagefile=$false} -PassThru") + powershell_exec! <<~EOH + $sys = Get-CimInstance Win32_ComputerSystem -Property * + Set-CimInstance -InputObject $sys -Property @{AutomaticManagedPagefile=$false} -PassThru + EOH + end end end @@ -239,14 +246,13 @@ class Chef # @param [String] min the minimum size of the pagefile # @param [String] max the minimum size of the pagefile def set_custom_size(pagefile, min, max) + unset_automatic_managed converge_by("set #{pagefile} to InitialSize=#{min} & MaximumSize=#{max}") do logger.trace("Set-CimInstance -Property @{InitialSize = #{min} MaximumSize = #{max}") powershell_exec! <<~EOD $page_file = "#{pagefile}" $driveLetter = $page_file.split(':')[0] - Get-CimInstance -ClassName Win32_PageFileSetting -Filter "SettingID='pagefile.sys @ $($driveLetter):'" -ErrorAction Stop | Set-CimInstance -Property @{ - InitialSize = #{min} - MaximumSize = #{max}} + Get-CimInstance -ClassName Win32_PageFileSetting -Filter "SettingID='pagefile.sys @ $($driveLetter):'" -ErrorAction Stop | Set-CimInstance -Property @{InitialSize = #{min}; MaximumSize = #{max};} EOD end end diff --git a/lib/chef/resource/windows_user_privilege.rb b/lib/chef/resource/windows_user_privilege.rb index e4679f50b9..251382e46f 100644 --- a/lib/chef/resource/windows_user_privilege.rb +++ b/lib/chef/resource/windows_user_privilege.rb @@ -23,7 +23,7 @@ class Chef class WindowsUserPrivilege < Chef::Resource provides :windows_user_privilege - description "The windows_user_privilege resource allows to add and set principal (User/Group) to the specified privilege.\n Ref: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment" + description "The windows_user_privilege resource allows to add and set principal (User/Group) to the specified privilege.\n Ref: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment\n For list of principals to use with :add action Ref: https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/special-identities" introduced "16.0" diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index ac5ec5d8e0..0d310f8bea 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -124,6 +124,13 @@ require_relative "resource/route" require_relative "resource/ruby" require_relative "resource/ruby_block" require_relative "resource/script" +require_relative "resource/selinux_boolean" +require_relative "resource/selinux_fcontext" +require_relative "resource/selinux_install" +require_relative "resource/selinux_module" +require_relative "resource/selinux_permissive" +require_relative "resource/selinux_port" +require_relative "resource/selinux_state" require_relative "resource/service" require_relative "resource/sudo" require_relative "resource/sysctl" diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index ce4d545aa4..11bfc6e3c6 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -413,9 +413,9 @@ class Chef logger.warn(<<~ERROR_MESSAGE) MissingCookbookDependency: Recipe `#{recipe_name}` is not in the run_list, and cookbook '#{cookbook_name}' - is not a dependency of any cookbook in the run_list. To load this recipe, - first add a dependency on cookbook '#{cookbook_name}' in the cookbook you're - including it from in that cookbook's metadata. + is not a dependency of any cookbook in the run_list. To load this recipe, + first add a dependency of the cookbook '#{cookbook_name}' into the metadata + of the cookbook which depends on '#{cookbook_name}'. ERROR_MESSAGE end diff --git a/lib/chef/secret_fetcher/azure_key_vault.rb b/lib/chef/secret_fetcher/azure_key_vault.rb index da7f0d2da5..3bbf576587 100644 --- a/lib/chef/secret_fetcher/azure_key_vault.rb +++ b/lib/chef/secret_fetcher/azure_key_vault.rb @@ -59,7 +59,7 @@ class Chef end def validate! - raise Chef::Exceptions::Secret::ConfigurationInvalid, "You may only specify one (these are mutually exclusive): :object_id, :client_id, or :mi_res_id" if [object_id, client_id, mi_res_id].count { |x| !x.nil? } > 1 + raise Chef::Exceptions::Secret::ConfigurationInvalid, "You may only specify one (these are mutually exclusive): :object_id, :client_id, or :mi_res_id" if [config_object_id, client_id, mi_res_id].count { |x| !x.nil? } > 1 end private @@ -87,7 +87,7 @@ class Chef "https://vault.azure.net" end - def object_id + def config_object_id config[:object_id] end @@ -104,7 +104,7 @@ class Chef p = {} p["api-version"] = api_version p["resource"] = resource - p["object_id"] = object_id if object_id + p["object_id"] = config_object_id if config_object_id p["client_id"] = client_id if client_id p["mi_res_id"] = mi_res_id if mi_res_id URI.encode_www_form(p) diff --git a/lib/chef/secret_fetcher/hashi_vault.rb b/lib/chef/secret_fetcher/hashi_vault.rb index 170fcba4b6..1b18c6345f 100644 --- a/lib/chef/secret_fetcher/hashi_vault.rb +++ b/lib/chef/secret_fetcher/hashi_vault.rb @@ -112,7 +112,7 @@ class Chef raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the authenticating Vault role name in the configuration as :role_name") end - Vault.auth.aws_iam(config[:role_name], Aws::InstanceProfileCredentials.new) + Vault.auth.aws_iam(config[:role_name], Aws::InstanceProfileCredentials.new, Vault.address) else raise Chef::Exceptions::Secret::ConfigurationInvalid.new("Invalid :auth_method provided. You gave #{config[:auth_method]}, expected one of :#{SUPPORTED_AUTH_TYPES.join(", :")} ") end diff --git a/lib/chef/version.rb b/lib/chef/version.rb index a4697c29a5..70592d4051 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -23,7 +23,7 @@ require_relative "version_string" class Chef CHEF_ROOT = File.expand_path("..", __dir__) - VERSION = Chef::VersionString.new("18.0.88") + VERSION = Chef::VersionString.new("18.0.155") end # diff --git a/lib/chef/win32/version.rb b/lib/chef/win32/version.rb index 65cf2fc5f0..a4a196ed4a 100644 --- a/lib/chef/win32/version.rb +++ b/lib/chef/win32/version.rb @@ -51,7 +51,8 @@ class Chef WIN_VERSIONS = { "Windows Server 2022" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 20348 } }, "Windows Server 2019" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 17763 && build_number < 20348 } }, - "Windows 10" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION } }, + "Windows 11" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION && build_number >= 22000 } }, + "Windows 10" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION && build_number >= 19044 && build_number < 22000 } }, "Windows Server 2016" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number <= 14393 } }, "Windows 8.1" => { major: 6, minor: 3, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION } }, "Windows Server 2012 R2" => { major: 6, minor: 3, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION } }, diff --git a/omnibus/Gemfile b/omnibus/Gemfile index ca5e4f2339..a8d16ac939 100644 --- a/omnibus/Gemfile +++ b/omnibus/Gemfile @@ -1,7 +1,9 @@ source "https://rubygems.org" gem "omnibus", github: ENV.fetch("OMNIBUS_GITHUB_REPO", "chef/omnibus"), branch: ENV.fetch("OMNIBUS_GITHUB_BRANCH", "main") + gem "omnibus-software", github: ENV.fetch("OMNIBUS_SOFTWARE_GITHUB_REPO", "chef/omnibus-software"), branch: ENV.fetch("OMNIBUS_SOFTWARE_GITHUB_BRANCH", "main") + gem "artifactory" gem "pedump" @@ -12,7 +14,7 @@ gem "pedump" # by running `bundle config set --local without development && bundle install` to speed up build times. group :development do # Use Berkshelf for resolving cookbook dependencies - gem "berkshelf", ">= 7.0" + gem "berkshelf", ">= 8.0" # Use Test Kitchen with Vagrant for converging the build environment gem "test-kitchen", ">= 1.23" diff --git a/omnibus/Gemfile.lock b/omnibus/Gemfile.lock index 42de91cb1e..9d2f1653b0 100644 --- a/omnibus/Gemfile.lock +++ b/omnibus/Gemfile.lock @@ -1,17 +1,17 @@ GIT remote: https://github.com/chef/omnibus-software.git - revision: 1451aa249ab4177da82d78665f7fbe5eab0186d8 + revision: fc901c6446e6354058133b89a29a6ef8e2995b3d branch: main specs: omnibus-software (4.0.0) - omnibus (>= 8.0.0) + omnibus (>= 9.0.0) GIT remote: https://github.com/chef/omnibus.git - revision: 124d5960ab2d3ed15b321d12d8da5b475631e16b + revision: 4b6901cf891474291368468b73301057ce9fadde branch: main specs: - omnibus (8.3.2) + omnibus (9.0.7) aws-sdk-s3 (~> 1) chef-cleanroom (~> 1.0) chef-utils (>= 15.4) @@ -22,6 +22,7 @@ GIT mixlib-versioning ohai (>= 15, < 18) pedump + rexml (~> 3.2) ruby-progressbar (~> 1.7) thor (>= 0.18, < 2.0) @@ -33,28 +34,26 @@ GEM artifactory (3.0.15) awesome_print (1.9.2) aws-eventstream (1.2.0) - aws-partitions (1.571.0) - aws-sdk-core (3.130.0) + aws-partitions (1.610.0) + aws-sdk-core (3.131.3) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) - jmespath (~> 1.0) - aws-sdk-kms (1.55.0) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.58.0) aws-sdk-core (~> 3, >= 3.127.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.113.0) + aws-sdk-s3 (1.114.0) aws-sdk-core (~> 3, >= 3.127.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sdk-secretsmanager (1.59.0) + aws-sdk-secretsmanager (1.64.0) aws-sdk-core (~> 3, >= 3.127.0) aws-sigv4 (~> 1.1) - aws-sigv4 (1.4.0) + aws-sigv4 (1.5.1) aws-eventstream (~> 1, >= 1.0.2) bcrypt_pbkdf (1.1.0) - bcrypt_pbkdf (1.1.0-x64-mingw32) - bcrypt_pbkdf (1.1.0-x86-mingw32) - berkshelf (7.2.2) + berkshelf (8.0.2) chef (>= 15.7.32) chef-config cleanroom (~> 1.0) @@ -142,7 +141,7 @@ GEM win32-service (>= 2.1.5, < 3.0) win32-taskscheduler (~> 2.0) wmi-lite (~> 1.0) - chef-cleanroom (1.0.4) + chef-cleanroom (1.0.5) chef-config (17.10.0) addressable chef-utils (= 17.10.0) @@ -158,7 +157,7 @@ GEM concurrent-ruby (~> 1.0) chef-utils (17.10.0) concurrent-ruby - chef-vault (4.1.5) + chef-vault (4.1.10) chef-zero (15.0.11) ffi-yajl (~> 2.2) hashie (>= 2.0, < 5.0) @@ -193,6 +192,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) ffi (1.15.5) + ffi (1.15.5-x64-mingw-ucrt) ffi (1.15.5-x64-mingw32) ffi (1.15.5-x86-mingw32) ffi-libarchive (1.1.3) @@ -204,12 +204,13 @@ GEM fuzzyurl (0.9.0) gssapi (1.3.1) ffi (>= 1.0.1) - gyoku (1.3.1) + gyoku (1.4.0) builder (>= 2.1.2) + rexml (~> 3.0) hashie (4.1.0) httpclient (2.8.3) iniparse (1.5.0) - inspec-core (4.56.19) + inspec-core (4.56.20) addressable (~> 2.4) chef-telemetry (~> 1.0, >= 1.0.8) faraday (>= 0.9.0, < 1.5) @@ -236,8 +237,8 @@ GEM ipaddress (0.8.3) iso8601 (0.13.0) jmespath (1.6.1) - json (2.6.1) - kitchen-vagrant (1.11.0) + json (2.6.2) + kitchen-vagrant (1.12.1) test-kitchen (>= 1.4, < 4) libyajl2 (2.1.0) license-acceptance (2.1.13) @@ -245,12 +246,12 @@ GEM tomlrb (>= 1.2, < 3.0) tty-box (~> 0.6) tty-prompt (~> 0.20) - license_scout (1.2.15) + license_scout (1.3.2) ffi-yajl (~> 2.2) mixlib-shellout (>= 2.2, < 4.0) toml-rb (>= 1, < 3) little-plugger (1.1.4) - logging (2.3.0) + logging (2.3.1) little-plugger (~> 1.1) multi_json (~> 1.14) method_source (1.0.0) @@ -261,16 +262,21 @@ GEM mixlib-log mixlib-authentication (3.0.10) mixlib-cli (2.1.8) - mixlib-config (3.0.9) + mixlib-config (3.0.27) tomlrb - mixlib-install (3.12.16) + mixlib-install (3.12.19) mixlib-shellout mixlib-versioning thor mixlib-log (3.0.9) - mixlib-shellout (3.2.6) + mixlib-shellout (3.2.7) chef-utils - mixlib-shellout (3.2.6-universal-mingw32) + mixlib-shellout (3.2.7-universal-mingw32) + chef-utils + ffi-win32-extensions (~> 1.0.3) + win32-process (~> 0.9) + wmi-lite (~> 1.0) + mixlib-shellout (3.2.7-x64-mingw-ucrt) chef-utils ffi-win32-extensions (~> 1.0.3) win32-process (~> 0.9) @@ -278,7 +284,7 @@ GEM mixlib-versioning (1.2.12) molinillo (0.8.0) multi_json (1.15.0) - multipart-post (2.1.1) + multipart-post (2.2.3) net-scp (3.0.0) net-ssh (>= 2.6.5, < 7.0.0) net-sftp (3.0.0) @@ -287,9 +293,9 @@ GEM net-ssh-gateway (2.0.0) net-ssh (>= 4.0.0) nori (2.6.0) - octokit (4.22.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) ohai (17.9.0) chef-config (>= 14.12, < 18) chef-utils (>= 16.0, < 18) @@ -318,10 +324,11 @@ GEM pry (0.14.1) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (4.0.6) - rack (2.2.3) + public_suffix (4.0.7) + rack (2.2.4) rainbow (3.1.1) retryable (3.0.5) + rexml (3.2.5) rspec (3.11.0) rspec-core (~> 3.11.0) rspec-expectations (~> 3.11.0) @@ -334,7 +341,7 @@ GEM rspec-its (1.3.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.11.0) + rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) rspec-support (3.11.0) @@ -342,10 +349,10 @@ GEM ruby2_keywords (0.0.5) rubyntlm (0.6.3) rubyzip (2.3.2) - sawyer (0.8.2) + sawyer (0.9.2) addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) - semverse (3.0.0) + faraday (>= 0.17.3, < 3) + semverse (3.0.2) solve (4.0.4) molinillo (~> 0.6) semverse (>= 1.1, < 4.0) @@ -357,7 +364,7 @@ GEM strings-ansi (0.2.0) structured_warnings (0.4.0) syslog-logger (1.6.8) - test-kitchen (3.2.2) + test-kitchen (3.3.1) bcrypt_pbkdf (~> 1.0) chef-utils (>= 16.4.35) ed25519 (~> 1.2) @@ -372,10 +379,10 @@ GEM winrm-elevated (~> 1.0) winrm-fs (~> 1.1) thor (1.2.1) - toml-rb (2.1.2) + toml-rb (2.2.0) citrus (~> 3.0, > 3.0) tomlrb (1.3.0) - train-core (3.8.9) + train-core (3.10.1) addressable (~> 2.5) ffi (!= 1.13.0) json (>= 1.8, < 3.0) @@ -404,16 +411,16 @@ GEM pastel (~> 0.8) strings (~> 0.2.0) tty-screen (~> 0.8) - unicode-display_width (2.1.0) + unicode-display_width (2.2.0) unicode_utils (1.4.0) uuidtools (2.2.0) - vault (0.16.0) + vault (0.17.0) aws-sigv4 webrick (1.7.0) - win32-api (1.10.1-universal-mingw32) - win32-certstore (0.6.2) + win32-api (1.10.1) + win32-certstore (0.6.15) + chef-powershell (>= 1.0.12) ffi - mixlib-shellout win32-event (0.6.3) win32-ipc (>= 0.6.0) win32-eventlog (0.6.3) @@ -424,7 +431,7 @@ GEM ffi win32-mutex (0.4.3) win32-ipc (>= 0.6.0) - win32-process (0.9.0) + win32-process (0.10.0) ffi (>= 1.0.0) win32-service (2.3.2) ffi @@ -432,15 +439,6 @@ GEM win32-taskscheduler (2.0.4) ffi structured_warnings - winrm (2.3.6) - builder (>= 2.1.2) - erubi (~> 1.8) - gssapi (~> 1.2) - gyoku (~> 1.0) - httpclient (~> 2.2, >= 2.2.0.2) - logging (>= 1.6.1, < 3.0) - nori (~> 2.0) - rubyntlm (~> 0.6.0, >= 0.6.3) winrm-elevated (1.2.3) erubi (~> 1.8) winrm (~> 2.0) @@ -451,17 +449,16 @@ GEM rubyzip (~> 2.0) winrm (~> 2.0) wisper (2.0.1) - wmi-lite (1.0.5) + wmi-lite (1.0.7) zhexdump (0.0.2) PLATFORMS ruby - x64-mingw32 - x86-mingw32 + x64-mingw-ucrt DEPENDENCIES artifactory - berkshelf (>= 7.0) + berkshelf (>= 8.0) kitchen-vagrant (>= 1.3.1) omnibus! omnibus-software! diff --git a/omnibus/config/projects/chef.rb b/omnibus/config/projects/chef.rb index dd22f4654c..217170ffef 100644 --- a/omnibus/config/projects/chef.rb +++ b/omnibus/config/projects/chef.rb @@ -62,11 +62,7 @@ dependency "version-manifest" dependency "openssl-customization" # devkit needs to come dead last these days so we do not use it to compile any gems -if windows? - override :"ruby-windows-devkit", version: "4.5.2-20111229-1559" if windows_arch_i386? - dependency "ruby-windows-devkit" - dependency "ruby-windows-devkit-bash" -end +dependency "ruby-msys2-devkit" if windows? dependency "ruby-cleanup" @@ -98,8 +94,8 @@ package :msi do upgrade_code msi_upgrade_code wix_candle_extension "WixUtilExtension" wix_light_extension "WixUtilExtension" - signing_identity "AF21BA8C9E50AE20DA9907B6E2D4B0CC3306CA03", machine_store: true - parameters ChefLogDllPath: windows_safe_path(gem_path("chef-[0-9]*-mingw32/ext/win32-eventlog/chef-log.dll")), + signing_identity "13B510D1CF1B3467856A064F1BEA12D0884D2528", machine_store: true + parameters ChefLogDllPath: windows_safe_path(gem_path("chef-[0-9]*-x64-mingw-ucrt/ext/win32-eventlog/chef-log.dll")), ProjectLocationDir: project_location_dir end diff --git a/omnibus/omnibus-test.ps1 b/omnibus/omnibus-test.ps1 index 7e3488f060..2c4331ff2f 100644 --- a/omnibus/omnibus-test.ps1 +++ b/omnibus/omnibus-test.ps1 @@ -47,24 +47,36 @@ ForEach ($b in } Else { Write-Output "Error: Could not find $b" - exit 1 + Throw 1 } } $Env:PATH = "C:\opscode\chef\bin;$Env:PATH" chef-client --version +If ($lastexitcode -ne 0) { Throw $lastexitcode } # Exercise various packaged tools to validate binstub shebangs & $embedded_bin_dir\ruby --version +If ($lastexitcode -ne 0) { Throw $lastexitcode } + & $embedded_bin_dir\gem.bat --version +If ($lastexitcode -ne 0) { Throw $lastexitcode } + & $embedded_bin_dir\bundle.bat --version +If ($lastexitcode -ne 0) { Throw $lastexitcode } + & $embedded_bin_dir\rspec.bat --version +If ($lastexitcode -ne 0) { Throw $lastexitcode } -$Env:PATH = "C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;$Env:PATH" +# We add C:\Program Files\Git\bin to the path to ensure the git bash shell is included +# Omnibus puts C:\Program Files\Git\mingw64\bin which has git.exe but not bash.exe +$Env:PATH = "C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;C:\Program Files\Git\bin;$Env:PATH" # Test against the vendored chef gem (cd into the output of "gem which chef") $chefdir = gem which chef +If ($lastexitcode -ne 0) { Throw $lastexitcode } + $chefdir = Split-Path -Path "$chefdir" -Parent $chefdir = Split-Path -Path "$chefdir" -Parent Set-Location -Path $chefdir @@ -79,9 +91,10 @@ $Env:CHEF_LICENSE = "accept-no-persist" # some tests need winrm configured winrm quickconfig -quiet +If ($lastexitcode -ne 0) { Throw $lastexitcode } bundle -If ($lastexitcode -ne 0) { Exit $lastexitcode } +If ($lastexitcode -ne 0) { Throw $lastexitcode } # buildkite changes the casing of the Path variable to PATH # It is not clear how or where that happens, but it breaks the choco @@ -98,11 +111,17 @@ $exit = 0 bundle exec rspec -f progress --profile -- ./spec/unit If ($lastexitcode -ne 0) { $exit = 1 } +Write-Output "Last exit code: $lastexitcode" +Write-Output "" bundle exec rspec -f progress --profile -- ./spec/functional If ($lastexitcode -ne 0) { $exit = 1 } +Write-Output "Last exit code: $lastexitcode" +Write-Output "" bundle exec rspec -f progress --profile -- ./spec/integration If ($lastexitcode -ne 0) { $exit = 1 } +Write-Output "Last exit code: $lastexitcode" +Write-Output "" -Exit $exit +If ($exit -ne 0) { Throw $exit } diff --git a/omnibus_overrides.rb b/omnibus_overrides.rb index e65b24c0c7..3bd6af7bf5 100644 --- a/omnibus_overrides.rb +++ b/omnibus_overrides.rb @@ -16,12 +16,13 @@ override "libxslt", version: windows? ? "1.1.34" : "1.1.35" override "libyaml", version: "0.1.7" override "makedepend", version: "1.0.5" -override "ncurses", version: "5.9" +override "ncurses", version: "6.3" override "nokogiri", version: "1.13.1" override "openssl", version: mac_os_x? ? "1.1.1m" : "1.0.2zb" override "pkg-config-lite", version: "0.28-1" -override "ruby", version: "3.0.3" +override :ruby, version: aix? ? "3.0.3" : "3.1.2" override "ruby-windows-devkit-bash", version: "3.1.23-4-msys-1.0.18" +override "ruby-msys2-devkit", version: "3.1.2-1" override "util-macros", version: "1.19.0" override "xproto", version: "7.0.28" override "zlib", version: "1.2.11" diff --git a/post-bundle-install.rb b/post-bundle-install.rb index 86a530bffd..f3b953e7e3 100644 --- a/post-bundle-install.rb +++ b/post-bundle-install.rb @@ -18,7 +18,7 @@ Dir["#{gem_home}/bundler/gems/*"].each do |gempath| next unless gem_name # FIXME: should omit the gem which is in the current directory and not hard code chef - next if %w{chef chef-universal-mingw32}.include?(gem_name) + next if %w{chef chef-universal-mingw-ucrt}.include?(gem_name) puts "re-installing #{gem_name}..." diff --git a/spec/data/rubygems.org/sexp_processor-info b/spec/data/rubygems.org/sexp_processor-info index a37139f592..cc371e0d1a 100644 --- a/spec/data/rubygems.org/sexp_processor-info +++ b/spec/data/rubygems.org/sexp_processor-info @@ -47,3 +47,4 @@ 4.14.1 |checksum:0fa8731445cf4a0c01570ec29aac4b50a0451ce66b1b31ad768f5035e3af7b90,ruby:~> 2.2 4.15.0 |checksum:a5ec27d8055ad47444cfb7ce860bad8af2365772a82892f4a8a0d97e8e9e3b34,ruby:~> 2.2 4.15.1 |checksum:9291a0f2247f50d15068ee6965b67cd7b678b0d273e18adf3c0b2ea4a890125c,ruby:>= 2.1 +4.16.1 |checksum:5caadbf4bbe5ab539cb892a5bcf74ca33a2f2a897cecafdee4a63be79b4819dc,ruby:>= 2.1 diff --git a/spec/functional/resource/group_spec.rb b/spec/functional/resource/group_spec.rb index 87953455b9..9360020537 100644 --- a/spec/functional/resource/group_spec.rb +++ b/spec/functional/resource/group_spec.rb @@ -425,7 +425,7 @@ describe Chef::Resource::Group, :requires_root_or_running_windows do end end - describe "when there is a group" do + describe "when there is a group", :not_supported_on_freebsd_gte_12_3 do it_behaves_like "correct group management" end @@ -463,7 +463,7 @@ describe Chef::Resource::Group, :requires_root_or_running_windows do end end - describe "when there is a group" do + describe "when there is a group", :not_supported_on_freebsd_gte_12_3 do it_behaves_like "correct group management" end diff --git a/spec/functional/resource/windows_certificate_spec.rb b/spec/functional/resource/windows_certificate_spec.rb index df2d1cbec8..9552d559b3 100644 --- a/spec/functional/resource/windows_certificate_spec.rb +++ b/spec/functional/resource/windows_certificate_spec.rb @@ -89,7 +89,9 @@ describe Chef::Resource::WindowsCertificate, :windows_only do end - after { delete_store } + after do + delete_store + end describe "action: create" do it "starts with no certificates" do @@ -195,7 +197,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do create_store end it "fails with no certificates in the store" do - expect(Chef::Log).to receive(:info).with("Certificate not found") + expect(Chef::Log).to receive(:info).with("Certificate not valid") resource.source = tests_thumbprint resource.run_action(:verify) @@ -219,7 +221,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do end it "fails with an invalid thumbprint" do - expect(Chef::Log).to receive(:info).with("Certificate not found") + expect(Chef::Log).to receive(:info).with("Certificate not valid") resource.source = others_thumbprint resource.run_action(:verify) @@ -253,7 +255,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do end it "fails with an invalid thumbprint" do - expect(Chef::Log).to receive(:info).with("Certificate not found") + expect(Chef::Log).to receive(:info).with("Certificate not valid") resource.source = others_thumbprint resource.run_action(:verify) @@ -265,11 +267,11 @@ describe Chef::Resource::WindowsCertificate, :windows_only do describe "action: fetch" do context "with no certificate in the store" do - it "throws an error with no certificates in the store" do - expect(Chef::Log).not_to receive(:info) + it "logs a debug error with no certificates in the store" do + expect(Chef::Log).to receive(:debug).with("Certificate Not Found") resource.source = others_thumbprint resource.output_path = cert_output_path - expect { resource.run_action :fetch }.to raise_error(ArgumentError) + resource.run_action(:fetch) end end @@ -288,7 +290,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do end it "fails with an invalid thumbprint" do - expect(Chef::Log).not_to receive(:info) + expect(Chef::Log).to receive(:debug).with("Certificate Not Found") resource.source = others_thumbprint @@ -296,7 +298,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do path = File.join(dir, "test.pem") resource.output_path = path - expect { resource.run_action :fetch }.to raise_error(ArgumentError) + resource.run_action(:fetch) end end @@ -340,9 +342,10 @@ describe Chef::Resource::WindowsCertificate, :windows_only do end describe "action: delete" do - it "throws an argument error when attempting to delete a certificate that doesn't exist" do + it "logs an error when attempting to delete a certificate that doesn't exist" do + expect(Chef::Log).to receive(:debug).with("Certificate Not Found") resource.source = tests_thumbprint - expect { resource.run_action :delete }.to raise_error(ArgumentError) + resource.run_action(:delete) end it "deletes an existing certificate while leaving other certificates alone" do @@ -360,7 +363,7 @@ describe Chef::Resource::WindowsCertificate, :windows_only do expect(certificate_count).to eq(1) expect(resource).to be_updated_by_last_action - expect { resource.run_action :delete }.to raise_error(ArgumentError) + expect { resource.run_action :delete }.not_to raise_error expect(certificate_count).to eq(1) expect(resource).not_to be_updated_by_last_action diff --git a/spec/functional/resource/windows_font_spec.rb b/spec/functional/resource/windows_font_spec.rb index e46e4aca17..92e7b0395c 100644 --- a/spec/functional/resource/windows_font_spec.rb +++ b/spec/functional/resource/windows_font_spec.rb @@ -37,13 +37,16 @@ describe Chef::Resource::WindowsFont, :windows_only do resource end - it "installs font on first install" do - subject.run_action(:install) - expect(subject).to be_updated_by_last_action - end + ## these were commented out because testing hangs in the verify pipeline with them enabled. WEIRD + ## that needs to be addressed - it "does not install font when already installed" do - subject.run_action(:install) - expect(subject).not_to be_updated_by_last_action - end + # it "installs font on first install" do + # subject.run_action(:install) + # expect(subject).to be_updated_by_last_action + # end + + # it "does not install font when already installed" do + # subject.run_action(:install) + # expect(subject).not_to be_updated_by_last_action + # end end diff --git a/spec/functional/resource/windows_pagefile_spec.rb b/spec/functional/resource/windows_pagefile_spec.rb index fd44c01973..9e4abc7e58 100644 --- a/spec/functional/resource/windows_pagefile_spec.rb +++ b/spec/functional/resource/windows_pagefile_spec.rb @@ -40,13 +40,32 @@ describe Chef::Resource::WindowsPagefile, :windows_only do new_resource end + def set_automatic_managed_to_false + powershell_code = <<~EOH + $computersys = Get-WmiObject Win32_ComputerSystem -EnableAllPrivileges; + $computersys.AutomaticManagedPagefile = $False; + $computersys.Put(); + EOH + powershell_exec!(powershell_code) + end + + def set_automatic_managed_to_true + powershell_code = <<~EOH + $computersys = Get-WmiObject Win32_ComputerSystem -EnableAllPrivileges; + $computersys.AutomaticManagedPagefile = $True; + $computersys.Put(); + EOH + powershell_exec!(powershell_code) + end + describe "Setting Up Pagefile Management" do context "Disable Automatic Management" do - it "Disables Automatic Management" do + it "Verifies Automatic Management is Disabled" do + set_automatic_managed_to_false subject.path c_path subject.automatic_managed false subject.run_action(:set) - expect(subject).to be_updated_by_last_action + expect(subject).not_to be_updated_by_last_action end it "Enable Automatic Management " do @@ -55,6 +74,14 @@ describe Chef::Resource::WindowsPagefile, :windows_only do subject.run_action(:set) expect(subject).to be_updated_by_last_action end + + it "Disables Automatic Management" do + set_automatic_managed_to_true + subject.path c_path + subject.automatic_managed false + subject.run_action(:set) + expect(subject).to be_updated_by_last_action + end end end @@ -69,8 +96,8 @@ describe Chef::Resource::WindowsPagefile, :windows_only do context "Update a pagefile" do it "Changes a pagefile to use custom sizes" do subject.path c_path - subject.initial_size 20000 - subject.maximum_size 80000 + subject.initial_size 128 + subject.maximum_size 512 subject.run_action(:set) expect(subject).to be_updated_by_last_action end diff --git a/spec/functional/resource/zypper_package_spec.rb b/spec/functional/resource/zypper_package_spec.rb index 3d3a1db786..fbf394bae8 100644 --- a/spec/functional/resource/zypper_package_spec.rb +++ b/spec/functional/resource/zypper_package_spec.rb @@ -74,6 +74,18 @@ describe Chef::Resource::ZypperPackage, :requires_root, :suse_only do expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$") end + it "install package with source argument" do + zypper_package.source = "#{CHEF_SPEC_ASSETS}/zypprepo/chef_rpm-1.10-1.#{pkg_arch}.rpm" + zypper_package.run_action(:install) + expect(zypper_package.updated_by_last_action?).to be true + expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$") + end + + it "raises an error when passed a source that does not exist" do + zypper_package.source = "#{CHEF_SPEC_ASSETS}/false/zypprepo/chef_rpm-1.10-1.#{pkg_arch}.rpm" + expect { zypper_package.run_action(:install) }.to raise_error(Mixlib::ShellOut::ShellCommandFailed) + end + it "does not install if the package is installed" do preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm") zypper_package.run_action(:install) diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb index 3960123acd..1bd84fa940 100644 --- a/spec/integration/client/client_spec.rb +++ b/spec/integration/client/client_spec.rb @@ -37,7 +37,14 @@ describe "chef-client" do def install_certificate_in_store(client_name) if ChefUtils.windows? - powershell_exec!("New-SelfSignedCertificate -certstorelocation cert:\\localmachine\\my -Subject #{client_name} -FriendlyName #{client_name} -KeyExportPolicy Exportable") + powershell_exec! <<~EOH + if (-not (($PSVersionTable.PSVersion.Major -ge 5) -and ($PSVersionTable.PSVersion.Build -ge 22000)) ) { + New-SelfSignedCertificate -CertStoreLocation Cert:\\LocalMachine\\My -DnsName "#{client_name}" + } + else { + New-SelfSignedCertificate -CertStoreLocation Cert:\\LocalMachine\\My -Subject "#{client_name}" -FriendlyName "#{client_name}" -KeyExportPolicy Exportable + } + EOH end end @@ -65,13 +72,13 @@ describe "chef-client" do def verify_export_password_exists powershell_exec! <<~EOH - Try { - $response = Get-ItemPropertyValue -Path "HKLM:\\Software\\Progress\\Authentication" -Name "PfxPass" -ErrorAction Stop - if ($response) {return $true} - } - Catch { - return $false + Try { + $response = Get-ItemProperty -Path "HKLM:\\Software\\Progress\\Authentication" -Name "PfxPass" -ErrorAction Stop + if ($response) {return $true} } + Catch { + return $false + } EOH end diff --git a/spec/integration/recipes/use_partial_spec.rb b/spec/integration/recipes/use_partial_spec.rb index 17faf809f8..0a9fb06612 100644 --- a/spec/integration/recipes/use_partial_spec.rb +++ b/spec/integration/recipes/use_partial_spec.rb @@ -27,6 +27,7 @@ describe "notifying_block" do when_the_repository "has a cookbook with partial resources" do before do + ::Chef::HTTP::Authenticator.get_cert_password if windows? directory "cookbooks/x" do file "resources/_shared_properties.rb", <<-EOM property :content, String diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2aa3b2a1cd..bbf52b95fd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -144,6 +144,7 @@ RSpec.configure do |config| config.filter_run_excluding macos_only: true unless macos? config.filter_run_excluding not_macos_gte_11: true if macos_gte_11? config.filter_run_excluding not_supported_on_aix: true if aix? + config.filter_run_excluding not_supported_on_freebsd_gte_12_3: true if freebsd_gte_12_3? config.filter_run_excluding not_supported_on_solaris: true if solaris? config.filter_run_excluding not_supported_on_gce: true if gce? config.filter_run_excluding win2012r2_only: true unless windows_2012r2? diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb index 430d9b055f..6ed0945286 100644 --- a/spec/support/platform_helpers.rb +++ b/spec/support/platform_helpers.rb @@ -127,6 +127,10 @@ def freebsd? RUBY_PLATFORM.include?("freebsd") end +def freebsd_gte_12_3? + RUBY_PLATFORM.include?("freebsd") && !!(ohai[:platform_version].to_f >= 12.3) +end + def intel_64bit? !!(ohai[:kernel][:machine] == "x86_64") end diff --git a/spec/support/ruby_installer.rb b/spec/support/ruby_installer.rb index d03525268f..316f3a042d 100644 --- a/spec/support/ruby_installer.rb +++ b/spec/support/ruby_installer.rb @@ -48,4 +48,4 @@ rescue LoadError $stderr.puts "Failed to load ruby_installer. Assuming Ruby Installer is not being used." end -add_libarchive_dll_directory if RUBY_PLATFORM.match?(/mswin|mingw32|windows/) +add_libarchive_dll_directory if RUBY_PLATFORM.match?(/mswin|mingw|windows/) diff --git a/spec/support/shared/functional/windows_script.rb b/spec/support/shared/functional/windows_script.rb index 151ad2387c..1db85e35f5 100644 --- a/spec/support/shared/functional/windows_script.rb +++ b/spec/support/shared/functional/windows_script.rb @@ -163,7 +163,7 @@ shared_context Chef::Resource::WindowsScript do describe "when the run action is invoked on Windows" do it "executes the script code" do - resource.code("whoami > \"#{script_output_path}\"") + resource.code("chcp > \"#{script_output_path}\"") resource.returns(0) resource.run_action(:run) end @@ -199,7 +199,7 @@ shared_context Chef::Resource::WindowsScript do end it "executes the script code" do - resource.code("whoami > \"#{script_output_path}\"") + resource.code("chcp > \"#{script_output_path}\"") resource.returns(0) resource.run_action(:run) end diff --git a/spec/unit/cookbook/syntax_check_spec.rb b/spec/unit/cookbook/syntax_check_spec.rb index f9e7bc0d25..8741c89bda 100644 --- a/spec/unit/cookbook/syntax_check_spec.rb +++ b/spec/unit/cookbook/syntax_check_spec.rb @@ -159,12 +159,15 @@ describe Chef::Cookbook::SyntaxCheck do end describe "and a file has a syntax error" do + before do cookbook_path = File.join(CHEF_SPEC_DATA, "cookbooks", "borken") syntax_check.cookbook_path.replace(cookbook_path) end it "it indicates that a ruby file has a syntax error" do + expect(Chef::Log).to receive(:fatal).with("Cookbook file borken/recipes/default.rb has a ruby syntax error.") + allow(Chef::Log).to receive(:fatal) expect(syntax_check.validate_ruby_files).to be_falsey end diff --git a/spec/unit/http/authenticator_spec.rb b/spec/unit/http/authenticator_spec.rb index a1b67610c5..bbd952b436 100644 --- a/spec/unit/http/authenticator_spec.rb +++ b/spec/unit/http/authenticator_spec.rb @@ -32,7 +32,8 @@ describe Chef::HTTP::Authenticator, :windows_only do Chef::Config[:node_name] = node_name cert_name = "chef-#{node_name}" d = Time.now - end_date = Time.new(d.year, d.month + 3, d.day, d.hour, d.min, d.sec).utc.iso8601 + end_date = Time.new + (3600 * 24 * 90) + end_date = end_date.utc.iso8601 my_client = Chef::Client.new pfx = my_client.generate_pfx_package(cert_name, end_date) diff --git a/spec/unit/provider/mount/linux_spec.rb b/spec/unit/provider/mount/linux_spec.rb index 188777a19b..21f45d7fdd 100644 --- a/spec/unit/provider/mount/linux_spec.rb +++ b/spec/unit/provider/mount/linux_spec.rb @@ -25,6 +25,7 @@ describe Chef::Provider::Mount::Linux do allow(::File).to receive(:exists?).with("/dev/sdz1").and_return true allow(::File).to receive(:exists?).with("/tmp/foo").and_return true allow(::File).to receive(:exists?).with("//192.168.11.102/Share/backup").and_return true + allow(::File).to receive(:exists?).with("//192.168.11.102/Share/backup folder").and_return true allow(::File).to receive(:realpath).with("/dev/sdz1").and_return "/dev/sdz1" allow(::File).to receive(:realpath).with("/tmp/foo").and_return "/tmp/foo" end @@ -103,6 +104,15 @@ describe Chef::Provider::Mount::Linux do provider.load_current_resource expect(provider.current_resource.mounted).to be_truthy end + + it "should set mounted true if device name has a space and the mount point is found in the mounts list" do + new_resource.device "//192.168.11.102/Share/backup folder" + new_resource.fstype "cifs" + mount = "/tmp/foo //192.168.11.102/Share/backup\x20folder cifs rw\n" + allow(provider).to receive(:shell_out!).and_return(double(stdout: mount)) + provider.load_current_resource + expect(provider.current_resource.mounted).to be_truthy + end end context "to check if loop resource is mounted" do diff --git a/spec/unit/provider/package/rubygems_spec.rb b/spec/unit/provider/package/rubygems_spec.rb index a4ffc1712e..90695f8ef1 100644 --- a/spec/unit/provider/package/rubygems_spec.rb +++ b/spec/unit/provider/package/rubygems_spec.rb @@ -139,11 +139,11 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do .to_return(status: 200, body: "", headers: {}) stub_request(:get, "https://rubygems2.org/info/sexp_processor") .to_return(status: 200, body: File.binread(File.join(CHEF_SPEC_DATA, "rubygems.org", "sexp_processor-info"))) - stub_request(:get, "https://rubygems2.org/quick/Marshal.4.8/sexp_processor-4.15.1.gemspec.rz") + stub_request(:get, "https://rubygems2.org/quick/Marshal.4.8/sexp_processor-4.16.1.gemspec.rz") .to_return(status: 200, body: File.binread(File.join(CHEF_SPEC_DATA, "rubygems.org", "sexp_processor-4.15.1.gemspec.rz"))) dep = Gem::Dependency.new("sexp_processor", ">= 0") - expect(@gem_env.candidate_version_from_remote(dep, "https://rubygems2.org")).to be_kind_of(Gem::Version) + expect(@gem_env.candidate_version_from_remote(dep, "https://rubygems2.org")).to be_nil end end diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb index a1f6629f55..2850a70560 100644 --- a/spec/unit/provider/package/zypper_spec.rb +++ b/spec/unit/provider/package/zypper_spec.rb @@ -32,6 +32,8 @@ describe Chef::Provider::Package::Zypper do let(:status) { double(stdout: "\n", exitstatus: 0) } + let(:source) { "/tmp/wget_1.11.4-1ubuntu1_amd64.rpm" } + before(:each) do allow(Chef::Resource::Package).to receive(:new).and_return(current_resource) allow(provider).to receive(:shell_out_compacted!).and_return(status) @@ -163,6 +165,21 @@ describe Chef::Provider::Package::Zypper do ) provider.install_package(["emacs"], ["1.0"]) end + + it "should run zypper install with source option" do + new_resource.source "/tmp/wget_1.11.4-1ubuntu1_amd64.rpm" + allow(::File).to receive(:exist?).with("/tmp/wget_1.11.4-1ubuntu1_amd64.rpm").and_return(true) + shell_out_expectation!( + "zypper", "--non-interactive", "install", "--auto-agree-with-licenses", "--oldpackage", "/tmp/wget_1.11.4-1ubuntu1_amd64.rpm" + ) + provider.install_package(["wget"], ["1.11.4-1ubuntu1_amd64"]) + end + + it "should raise an exception if a source is supplied but not found when :install" do + new_resource.source "/tmp/blah/wget_1.11.4-1ubuntu1_amd64.rpm" + allow(::File).to receive(:exist?).with(new_resource.source).and_return(false) + expect { provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package) + end end describe "upgrade_package" do @@ -200,6 +217,21 @@ describe Chef::Provider::Package::Zypper do ) provider.upgrade_package(["emacs"], ["1.0"]) end + + it "should run zypper upgrade with source option" do + new_resource.source "/tmp/wget_1.11.4-1ubuntu1_amd64.rpm" + allow(::File).to receive(:exist?).with("/tmp/wget_1.11.4-1ubuntu1_amd64.rpm").and_return(true) + shell_out_expectation!( + "zypper", "--non-interactive", "install", "--auto-agree-with-licenses", "--oldpackage", "/tmp/wget_1.11.4-1ubuntu1_amd64.rpm" + ) + provider.upgrade_package(["wget"], ["1.11.4-1ubuntu1_amd64"]) + end + + it "should raise an exception if a source is supplied but not found when :upgrade" do + new_resource.source "/tmp/blah/wget_1.11.4-1ubuntu1_amd64.rpm" + allow(::File).to receive(:exist?).with(new_resource.source).and_return(false) + expect { provider.run_action(:upgrade) }.to raise_error(Chef::Exceptions::Package) + end end describe "remove_package" do diff --git a/spec/unit/provider/user/linux_spec.rb b/spec/unit/provider/user/linux_spec.rb index 1f22d963da..1fc8e3c6a1 100644 --- a/spec/unit/provider/user/linux_spec.rb +++ b/spec/unit/provider/user/linux_spec.rb @@ -70,4 +70,54 @@ describe Chef::Provider::User::Linux do expect( provider.useradd_options ).to eql(["-m"]) end end + + describe "expire_date behavior" do + before(:each) do + @new_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) + @current_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) + end + + it "defaults expire_date to nil" do + expect( @new_resource.expire_date ).to be nil + end + + it "by default expire_date is nil and we use ''" do + expect( provider.universal_options ).to eql([]) + end + + it "setting expire_date to nil includes ''" do + @new_resource.expire_date nil + expect( provider.universal_options ).to eql([]) + end + + it "setting expire_date to 1982-04-16 includes -e" do + @new_resource.expire_date "1982-04-16" + expect( provider.universal_options ).to eql(["-e", "1982-04-16"]) + end + end + + describe "inactive behavior" do + before(:each) do + @new_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) + @current_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) + end + + it "defaults inactive to nil" do + expect( @new_resource.inactive ).to be nil + end + + it "by default inactive is nil and we use ''" do + expect( provider.universal_options ).to eql([]) + end + + it "setting inactive to nil includes ''" do + @new_resource.inactive nil + expect( provider.universal_options ).to eql([]) + end + + it "setting inactive to 90 includes -f" do + @new_resource.inactive 90 + expect( provider.universal_options ).to eql(["-f", 90]) + end + end end diff --git a/spec/unit/provider/user_spec.rb b/spec/unit/provider/user_spec.rb index c8ad656f06..67cb2debf8 100644 --- a/spec/unit/provider/user_spec.rb +++ b/spec/unit/provider/user_spec.rb @@ -178,12 +178,30 @@ describe Chef::Provider::User do end end - it "should fail assertions when ruby-shadow cannot be loaded" do - expect(@provider).to receive(:require).with("shadow") { raise LoadError } - @provider.load_current_resource - @provider.action = :create - @provider.define_resource_requirements - expect { @provider.process_resource_requirements }.to raise_error Chef::Exceptions::MissingLibrary + context "when ruby-shadow is supported on the platform" do + before do + allow(@provider).to receive(:supports_ruby_shadow?).and_return true + end + it "should fail assertions when ruby-shadow cannot be loaded" do + expect(@provider).to receive(:require).with("shadow") { raise LoadError } + @provider.load_current_resource + @provider.action = :create + @provider.define_resource_requirements + expect { @provider.process_resource_requirements }.to raise_error Chef::Exceptions::MissingLibrary + end + end + + context "when ruby-shadow is not supported on the platform" do + before do + allow(@provider).to receive(:supports_ruby_shadow?).and_return false + end + it "should not fail any assertions when ruby-shadow cannot be loaded" do + expect(@provider).to receive(:require).with("shadow") { raise LoadError } + @provider.load_current_resource + @provider.action = :create + @provider.define_resource_requirements + @provider.process_resource_requirements + end end end diff --git a/spec/unit/resource/archive_file_spec.rb b/spec/unit/resource/archive_file_spec.rb index 7818a31516..c9793760d3 100644 --- a/spec/unit/resource/archive_file_spec.rb +++ b/spec/unit/resource/archive_file_spec.rb @@ -29,7 +29,7 @@ rescue LoadError end end -describe Chef::Resource::ArchiveFile, :not_supported_on_aix do +describe Chef::Resource::ArchiveFile, :not_supported_on_aix, :not_supported_on_windows do let(:node) { Chef::Node.new } let(:events) { Chef::EventDispatch::Dispatcher.new } let(:run_context) { Chef::RunContext.new(node, {}, events) } diff --git a/spec/unit/resource/chef_client_cron_spec.rb b/spec/unit/resource/chef_client_cron_spec.rb index b738a20a3a..cc72c38a39 100644 --- a/spec/unit/resource/chef_client_cron_spec.rb +++ b/spec/unit/resource/chef_client_cron_spec.rb @@ -43,6 +43,11 @@ describe Chef::Resource::ChefClientCron do expect { resource.splay("-10") }.to raise_error(Chef::Exceptions::ValidationFailed) end + it "set splay to 0" do + resource.splay "0" + expect(resource.splay).to eql(0) + end + it "builds a default value for chef_binary_path dist values" do expect(resource.chef_binary_path).to eql("/opt/chef/bin/chef-client") end diff --git a/spec/unit/resource/chef_client_launchd_spec.rb b/spec/unit/resource/chef_client_launchd_spec.rb index 1d0015cb0d..93d56a784e 100644 --- a/spec/unit/resource/chef_client_launchd_spec.rb +++ b/spec/unit/resource/chef_client_launchd_spec.rb @@ -43,6 +43,11 @@ describe Chef::Resource::ChefClientLaunchd do expect { resource.splay("-10") }.to raise_error(Chef::Exceptions::ValidationFailed) end + it "set splay to 0" do + resource.splay "0" + expect(resource.splay).to eql(0) + end + it "builds a default value for chef_binary_path dist values" do expect(resource.chef_binary_path).to eql("/opt/chef/bin/chef-client") end diff --git a/spec/unit/resource/chef_client_scheduled_task_spec.rb b/spec/unit/resource/chef_client_scheduled_task_spec.rb index bf165d4b70..45ed8c0602 100644 --- a/spec/unit/resource/chef_client_scheduled_task_spec.rb +++ b/spec/unit/resource/chef_client_scheduled_task_spec.rb @@ -43,6 +43,11 @@ describe Chef::Resource::ChefClientScheduledTask do expect { resource.splay("-10") }.to raise_error(Chef::Exceptions::ValidationFailed) end + it "set splay to 0" do + resource.splay "0" + expect(resource.splay).to eql(0) + end + it "coerces frequency_modifier to an Integer" do resource.frequency_modifier "10" expect(resource.frequency_modifier).to eql(10) diff --git a/spec/unit/resource/chef_client_systemd_timer_spec.rb b/spec/unit/resource/chef_client_systemd_timer_spec.rb index dfe01973fb..5fe4e80146 100644 --- a/spec/unit/resource/chef_client_systemd_timer_spec.rb +++ b/spec/unit/resource/chef_client_systemd_timer_spec.rb @@ -105,4 +105,4 @@ describe Chef::Resource::ChefClientSystemdTimer do expect(provider.service_content["Service"]["CPUQuota"]).to eq(50) end end -end
\ No newline at end of file +end diff --git a/spec/unit/resource/cron_d_spec.rb b/spec/unit/resource/cron_d_spec.rb index c798265d06..355f3ebb28 100644 --- a/spec/unit/resource/cron_d_spec.rb +++ b/spec/unit/resource/cron_d_spec.rb @@ -18,7 +18,11 @@ require "spec_helper" describe Chef::Resource::CronD do - let(:resource) { Chef::Resource::CronD.new("cronify") } + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::CronD.new("cronify", run_context) } + let(:provider) { resource.provider_for_action(:create) } it "has a default action of [:create]" do expect(resource.action).to eql([:create]) @@ -34,6 +38,38 @@ describe Chef::Resource::CronD do expect(resource.cron_name).to eql("cronify") end + context "on linux" do + before(:each) do + node.automatic_attrs[:os] = "linux" + end + + it "the cron_name property is valid" do + provider.define_resource_requirements + + expect { resource.cron_name "cron-job"; provider.process_resource_requirements }.not_to raise_error + expect { resource.cron_name "cron_job_0"; provider.process_resource_requirements }.not_to raise_error + expect { resource.cron_name "CronJob"; provider.process_resource_requirements }.not_to raise_error + expect { resource.cron_name "cron!"; provider.process_resource_requirements }.to raise_error "The cron job name should contain letters, numbers, hyphens and underscores only." + expect { resource.cron_name "cron job"; provider.process_resource_requirements }.to raise_error "The cron job name should contain letters, numbers, hyphens and underscores only." + end + end + + context "not on linux" do + before(:each) do + node.automatic_attrs[:os] = "aix" + end + + it "all cron names are valid" do + provider.define_resource_requirements + + expect { resource.cron_name "cron-job"; provider.process_resource_requirements }.not_to raise_error + expect { resource.cron_name "cron_job_0"; provider.process_resource_requirements }.not_to raise_error + expect { resource.cron_name "CronJob"; provider.process_resource_requirements }.not_to raise_error + expect { resource.cron_name "cron!"; provider.process_resource_requirements }.not_to raise_error + expect { resource.cron_name "cron job"; provider.process_resource_requirements }.not_to raise_error + end + end + it "the mode property defaults to '0600'" do expect(resource.mode).to eql("0600") end diff --git a/spec/unit/resource/selinux_boolean_spec.rb b/spec/unit/resource/selinux_boolean_spec.rb new file mode 100644 index 0000000000..63af7c5a3b --- /dev/null +++ b/spec/unit/resource/selinux_boolean_spec.rb @@ -0,0 +1,92 @@ +# +# Copyright:: Copyright (c) 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::SelinuxBoolean do + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::SelinuxBoolean.new("fakey_fakerton", run_context) } + let(:provider) { resource.provider_for_action(:set) } + let(:selinux_state) { double("shellout!", stdout: "permissive") } + + it "sets boolean proprty as name_property" do + expect(resource.boolean).to eql("fakey_fakerton") + end + + it "sets the default action as :set" do + expect(resource.action).to eql([:set]) + end + + it "supports :set action" do + expect { resource.action :set }.not_to raise_error + end + + context "coercing value property" do + it "should set value properly to 'on' when valid parameter is sent and is literal positive" do + resource.value = 1 + expect(resource.value).to eql("on") + + resource.value = "true" + expect(resource.value).to eql("on") + + resource.value = true + expect(resource.value).to eql("on") + end + + it "should set value properly to 'off' when valid parameter is sent and is literal negative" do + resource.value = 0 + expect(resource.value).to eql("off") + + resource.value = "false" + expect(resource.value).to eql("off") + + resource.value = false + expect(resource.value).to eql("off") + end + + it "should raise an exception if invalid parameter is sent" do + expect do + resource.value = "ON" + end.to raise_error(ArgumentError) + end + end + + describe "#Chef::SELinux::CommonHelpers" do + context "#selinux_permissive?" do + it "should return true if selinux_state is :permissive" do + allow(provider).to receive(:shell_out!).and_return(selinux_state) + expect(provider.selinux_permissive?).to eql(true) + end + end + + context "#selinux_disabled?" do + it "should return false if selinux_state is :permissive" do + allow(provider).to receive(:shell_out!).and_return(selinux_state) + expect(provider.selinux_disabled?).to eql(false) + end + end + + context "#selinux_enforcing?" do + it "should return false if selinux_state is :permissive" do + allow(provider).to receive(:shell_out!).and_return(selinux_state) + expect(provider.selinux_enforcing?).to eql(false) + end + end + end +end
\ No newline at end of file diff --git a/spec/unit/resource/selinux_fcontext_spec.rb b/spec/unit/resource/selinux_fcontext_spec.rb new file mode 100644 index 0000000000..7e1c31c23e --- /dev/null +++ b/spec/unit/resource/selinux_fcontext_spec.rb @@ -0,0 +1,65 @@ +# +# Copyright:: Copyright (c) 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::SelinuxFcontext do + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::SelinuxFcontext.new("fakey_fakerton", run_context) } + let(:provider) { resource.provider_for_action(:manage) } + let(:restoreconf) { double("shellout", stdout: "restorecon reset /var/www/html/index.html context unconfined_u:object_r:user_home_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0") } + + it "sets file_spec proprty as name_property" do + expect(resource.file_spec).to eql("fakey_fakerton") + end + + it "sets the default action as :manage" do + expect(resource.action).to eql([:manage]) + end + + it "supports :manage, :addormodify, :add, :modify, :delete actions" do + expect { resource.action :manage }.not_to raise_error + expect { resource.action :addormodify }.not_to raise_error + expect { resource.action :add }.not_to raise_error + expect { resource.action :modify }.not_to raise_error + expect { resource.action :delete }.not_to raise_error + end + + it "checks 'a', 'f', 'd', 'c', 'b', 's', 'l', 'p' as valid file_type property values" do + expect { resource.file_type "a" }.not_to raise_error + expect { resource.file_type "f" }.not_to raise_error + expect { resource.file_type "d" }.not_to raise_error + expect { resource.file_type "c" }.not_to raise_error + expect { resource.file_type "b" }.not_to raise_error + expect { resource.file_type "s" }.not_to raise_error + expect { resource.file_type "l" }.not_to raise_error + expect { resource.file_type "p" }.not_to raise_error + end + + it "sets default value for file_type property to 'a'" do + expect(resource.file_type).to eql("a") + end + + describe "#relabel_files" do + it "returns verbose output with details of the file for which SELinux config is restored" do + allow(provider).to receive(:shell_out!).and_return(restoreconf) + expect(provider.relabel_files).to eql(restoreconf) + end + end +end
\ No newline at end of file diff --git a/spec/unit/resource/selinux_install_spec.rb b/spec/unit/resource/selinux_install_spec.rb new file mode 100644 index 0000000000..5e82dfb840 --- /dev/null +++ b/spec/unit/resource/selinux_install_spec.rb @@ -0,0 +1,60 @@ +# +# Copyright:: Copyright (c) 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::SelinuxInstall do + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::SelinuxInstall.new("fakey_fakerton", run_context) } + let(:provider) { resource.provider_for_action(:install) } + + it "sets the default action as :install" do + expect(resource.action).to eql([:install]) + end + + it "supports :install, :upgrade, :remove actions" do + expect { resource.action :install }.not_to raise_error + expect { resource.action :upgrade }.not_to raise_error + expect { resource.action :remove }.not_to raise_error + end + + it "sets default packages on 'rhel', 'fedora', 'amazon' platforms" do + node.automatic_attrs[:platform_family] = "rhel" + expect(resource.packages).to eql(%w{make policycoreutils selinux-policy selinux-policy-targeted selinux-policy-devel libselinux-utils setools-console}) + end + + it "sets default packages on debian irrespective of platform_version" do + node.automatic_attrs[:platform_family] = "debian" + expect(resource.packages).to eql(%w{make policycoreutils selinux-basics selinux-policy-default selinux-policy-dev auditd setools}) + end + + it "sets default packages on ubuntu 18.04 platforms" do + node.automatic_attrs[:platform_family] = "debian" + node.automatic_attrs[:platform] = "ubuntu" + node.automatic_attrs[:platform_version] = 18.04 + expect(resource.packages).to eql(%w{make policycoreutils selinux selinux-basics selinux-policy-default selinux-policy-dev auditd setools}) + end + + it "sets default packages on ubuntu platforms and versions other than 18.04" do + node.automatic_attrs[:platform_family] = "debian" + node.automatic_attrs[:platform] = "ubuntu" + node.automatic_attrs[:platform_version] = 20.04 + expect(resource.packages).to eql(%w{make policycoreutils selinux-basics selinux-policy-default selinux-policy-dev auditd setools}) + end +end
\ No newline at end of file diff --git a/spec/unit/resource/selinux_module_spec.rb b/spec/unit/resource/selinux_module_spec.rb new file mode 100644 index 0000000000..dadd9eb8fa --- /dev/null +++ b/spec/unit/resource/selinux_module_spec.rb @@ -0,0 +1,55 @@ +# +# +# Copyright:: Copyright (c) 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::SelinuxModule do + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::SelinuxModule.new("fakey_fakerton", run_context) } + let(:provider) { resource.provider_for_action(:create) } + + it "sets module_name property as name_property" do + expect(resource.module_name).to eql("fakey_fakerton") + end + + it "sets default value for base_dir property" do + expect(resource.base_dir).to eql("/etc/selinux/local") + end + + it "sets the default action as :create" do + expect(resource.action).to eql([:create]) + end + + it "supports :create, :delete, :install, :remove actions" do + expect { resource.action :create }.not_to raise_error + expect { resource.action :delete }.not_to raise_error + expect { resource.action :install }.not_to raise_error + expect { resource.action :remove }.not_to raise_error + end + + describe "#selinux_module_filepath" do + it "returns selinux module file path based upon base_dir property and module_name property" do + resource.base_dir = "/opt/selinux" + resource.module_name = "my_module" + file_type = "te" + expect(provider.selinux_module_filepath(file_type)).to eql("/opt/selinux/my_module.te") + end + end +end
\ No newline at end of file diff --git a/spec/unit/resource/selinux_permissive_spec.rb b/spec/unit/resource/selinux_permissive_spec.rb new file mode 100644 index 0000000000..96ee3c3c81 --- /dev/null +++ b/spec/unit/resource/selinux_permissive_spec.rb @@ -0,0 +1,39 @@ +# +# Copyright:: Copyright (c) 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::SelinuxPermissive do + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::SelinuxPermissive.new("fakey_fakerton", run_context) } + let(:provider) { resource.provider_for_action(:add) } + + it "sets context property as name_property" do + expect(resource.context).to eql("fakey_fakerton") + end + + it "sets the default action as :add" do + expect(resource.action).to eql([:add]) + end + + it "supports :add, :delete actions" do + expect { resource.action :add }.not_to raise_error + expect { resource.action :delete }.not_to raise_error + end +end
\ No newline at end of file diff --git a/spec/unit/resource/selinux_port_spec.rb b/spec/unit/resource/selinux_port_spec.rb new file mode 100644 index 0000000000..2ed14c5ef6 --- /dev/null +++ b/spec/unit/resource/selinux_port_spec.rb @@ -0,0 +1,42 @@ +# +# Copyright:: Copyright (c) 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::SelinuxPort do + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::SelinuxPort.new("5678", run_context) } + let(:provider) { resource.provider_for_action(:manage) } + + it "sets port property as name_property" do + expect(resource.port).to eql("5678") + end + + it "sets the default action as :manage" do + expect(resource.action).to eql([:manage]) + end + + it "supports :manage, :addormodify, :add, :modify, :delete actions" do + expect { resource.action :manage }.not_to raise_error + expect { resource.action :addormodify }.not_to raise_error + expect { resource.action :add }.not_to raise_error + expect { resource.action :modify }.not_to raise_error + expect { resource.action :delete }.not_to raise_error + end +end
\ No newline at end of file diff --git a/spec/unit/resource/selinux_state_spec.rb b/spec/unit/resource/selinux_state_spec.rb new file mode 100644 index 0000000000..356a872627 --- /dev/null +++ b/spec/unit/resource/selinux_state_spec.rb @@ -0,0 +1,46 @@ +# +# Copyright:: Copyright (c) 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::SelinuxState do + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::SelinuxState.new("5678", run_context) } + let(:provider) { resource.provider_for_action(:enforcing) } + + it "sets the default action as :enforcing" do + expect(resource.action).to eql([:enforcing]) + end + + it "sets default value for policy property for 'rhel', 'fedora', 'amazon' platforms" do + node.automatic_attrs[:platform_family] = "rhel" + expect(resource.policy).to eql("targeted") + end + + it "supports :enforcing, :permissive, :disabled actions" do + expect { resource.action :enforcing }.not_to raise_error + expect { resource.action :permissive }.not_to raise_error + expect { resource.action :disabled }.not_to raise_error + end + + it "sets default value for policy property for debian platforms" do + node.automatic_attrs[:platform_family] = "debian" + expect(resource.policy).to eql("default") + end +end
\ No newline at end of file diff --git a/spec/unit/resource/sysctl_spec.rb b/spec/unit/resource/sysctl_spec.rb index 47556f5ee8..42b0c77d83 100644 --- a/spec/unit/resource/sysctl_spec.rb +++ b/spec/unit/resource/sysctl_spec.rb @@ -62,14 +62,14 @@ describe Chef::Resource::Sysctl do context "when comment is a String" do it "Returns content for use with a file resource" do resource.comment("This sets foo / bar on our system") - expect(provider.contruct_sysctl_content).to eql("# This sets foo / bar on our system\nfoo = bar") + expect(provider.contruct_sysctl_content).to eql("# This sets foo / bar on our system\nfoo = bar\n") end end context "when comment is an Array" do it "Returns content for use with a file resource" do resource.comment(["This sets foo / bar on our system", "We need for baz"]) - expect(provider.contruct_sysctl_content).to eql("# This sets foo / bar on our system\n# We need for baz\nfoo = bar") + expect(provider.contruct_sysctl_content).to eql("# This sets foo / bar on our system\n# We need for baz\nfoo = bar\n") end end end diff --git a/spec/unit/resource/user/linux_user_spec.rb b/spec/unit/resource/user/linux_user_spec.rb new file mode 100644 index 0000000000..c9bd71b11d --- /dev/null +++ b/spec/unit/resource/user/linux_user_spec.rb @@ -0,0 +1,42 @@ +require "spec_helper" + +describe Chef::Resource::User, "initialize" do + let(:resource) { Chef::Resource::User::LinuxUser.new("notarealuser") } + + describe "inactive attribute" do + it "allows a string" do + resource.inactive "100" + expect(resource.inactive).to eql("100") + end + + it "allows an integer" do + resource.inactive 100 + expect(resource.inactive).to eql(100) + end + + it "does not allow a hash" do + expect { resource.inactive({ woot: "i found it" }) }.to raise_error(ArgumentError) + end + end + + describe "expire_date attribute" do + it "allows a string" do + resource.expire_date "100" + expect(resource.expire_date).to eql("100") + end + + it "does not allow an integer" do + expect { resource.expire_date(90) }.to raise_error(ArgumentError) + end + + it "does not allow a hash" do + expect { resource.expire_date({ woot: "i found it" }) }.to raise_error(ArgumentError) + end + end + + %w{inactive expire_date}.each do |prop| + it "sets #{prop} to nil" do + expect(resource.send(prop)).to eql(nil) + end + end +end diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index f0a624d5db..db355d44fa 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -371,6 +371,9 @@ describe Chef::Resource do end describe "to_text" do + + let(:sensitive_property_masked_value) { "sensitive value suppressed" } + it "prints nice message" do resource_class = Class.new(Chef::Resource) { property :foo, String } resource = resource_class.new("sensitive_property_tests") @@ -383,7 +386,24 @@ describe Chef::Resource do resource_class = Class.new(Chef::Resource) { property :foo, String, sensitive: true } resource = resource_class.new("sensitive_property_tests") resource.foo = "some value" - expect(resource.to_text).to match(/foo "\*sensitive value suppressed\*"/) + expect(resource.to_text).to match(/foo "\*#{sensitive_property_masked_value}\*"/) + end + it "suppresses that properties value irrespective of desired state (false) " do + resource_class = Class.new(Chef::Resource) { + property :suppressed_content, String, sensitive: true, desired_state: false + } + resource = resource_class.new("desired_state_property_tests") + resource.suppressed_content = "some value" + expect(resource.to_text).to match(/suppressed_content "\*#{sensitive_property_masked_value}\*"/) + end + + it "suppresses that properties value irrespective of desired state (true) " do + resource_class = Class.new(Chef::Resource) { + property :desired_state_content, String, sensitive: true, desired_state: true + } + resource = resource_class.new("desired_state_property_tests") + resource.desired_state_content = "some value" + expect(resource.to_text).to match(/desired_state_content "\*#{sensitive_property_masked_value}\*"/) end end diff --git a/tasks/dependencies.rb b/tasks/dependencies.rb index f83b1c356c..8936203119 100644 --- a/tasks/dependencies.rb +++ b/tasks/dependencies.rb @@ -33,7 +33,7 @@ namespace :dependencies do Dir.chdir(dir) do Bundler.with_unbundled_env do rm_f "#{dir}/Gemfile.lock" - sh "bundle lock --update --add-platform ruby x64-mingw32 x86-mingw32" + sh "bundle lock --update --add-platform ruby x64-mingw-ucrt" end end end |