From 2934e18a7030fdb7f52fecde2b1a3f44704623ec Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 22 Oct 2015 23:47:57 -0500 Subject: [PATCH 01/14] Download and install powershell modules using ruby This will allow the powershell_module to work on Core installations of Windows. It does however it adds a dependency on the rubyzip gem. --- README.md | 7 +++-- libraries/powershell_module_provider.rb | 40 +++++++++++++++++++++++-- recipes/default.rb | 2 ++ 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index df3653d..2816616 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,8 @@ end ### `powershell_module` -Installs or uninstalls a Powershell module +Installs or uninstalls a Powershell module. You either need to install rubyzip with chef_gem or +include the default recipe before using this resource. #### Actions @@ -188,6 +189,8 @@ Installs or uninstalls a Powershell module #### Examples ```ruby +include_recipe 'powershell::default' + # Install module from local directory path # change the package_name and source powershell_module "PsUrl" do @@ -231,7 +234,7 @@ Usage ### default -The default recipe does nothing. +The default recipe is needs to be included before using the powershell_module recipe. ### powershell2 diff --git a/libraries/powershell_module_provider.rb b/libraries/powershell_module_provider.rb index e69c9c6..145996b 100644 --- a/libraries/powershell_module_provider.rb +++ b/libraries/powershell_module_provider.rb @@ -85,6 +85,41 @@ def uninstall_module end end + def download(download_url, target) + uri = URI(download_url) + + Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http| + f = open(target, 'wb') + http.request_get(uri.path) do |resp| + resp.read_body do |segment| + f.write(segment) + end + end + + f.close + end + end + + def unzip(zip_file, target_directory) + begin + require 'zip' + rescue LoadError + raise( + 'Could not load the rubyzip gem, please make sure this gem is installed with the "chef_gem" resource ' \ + 'or include the powershell::default recipe before using powershell_module.' + ) + end + + Zip::File.open(zip_file) do |zip| + + zip.each do |entry| + FileUtils::mkdir_p(::File.join(target_directory, ::File.dirname(entry.name))) + entry.extract(::File.join(target_directory, entry.name)) + end + + end + end + def download_extract_module(download_url = nil, target = nil) filename = @new_resource.package_name + '.zip' @@ -97,7 +132,6 @@ def download_extract_module(download_url = nil, target = nil) ps_module_path = sanitize! @new_resource.destination Chef::Log.debug("Powershell Module ps_module_path is #{ps_module_path}") - cmd_str = "powershell.exe Invoke-WebRequest #{download_url} -OutFile #{target}; $shell = new-object -com shell.application;$zip = $shell.NameSpace('#{target.gsub('/', '\\\\')}'); $shell.Namespace('#{ps_module_path}').copyhere($zip.items(), 0x14);write-host $shell" installed_module = module_exists?(ps_module_path, "*#{@new_resource.package_name}*") @@ -105,8 +139,8 @@ def download_extract_module(download_url = nil, target = nil) Chef::Log.info("Powershell Module #{@new_resource.package_name} already installed.") Chef::Log.info("Remove path at #{ps_module_path}\\#{installed_module} to reinstall.") else - ps_cmd = Mixlib::ShellOut.new(cmd_str) - ps_cmd.run_command + download(download_url, target) + unzip(target, ps_module_path) end target diff --git a/recipes/default.rb b/recipes/default.rb index 820ec12..b1dc26a 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -18,3 +18,5 @@ # See the License for the specific language governing permissions and # limitations under the License. # + +chef_gem 'rubyzip' From 79ae72991b6fa131c7a7a387cecfe2854467719b Mon Sep 17 00:00:00 2001 From: Baptiste Courtois Date: Sat, 28 Nov 2015 17:05:22 +0100 Subject: [PATCH 02/14] Use all-in-one ms_dotnet cookbook ms_dotnet is a 'all-in-one' cookbook allowing you to configure almost all .NET versions; It has been written following the same model as this powershell cookbook and is actively maintained by @criteo. Reason for this migration: * Having a single dependency to setup .NET is better than multiple ones. * ms_dotnet is more up-to-date than others cookbooks * ms_dotnet is going to support .NET 4.6 soon * ms_dotnet is rspec testable on linux using ohais instead of Win32 API Other changes: * Because a single recipe takes care of .NET 4 & 4.5, if attributes are not set properly powershell4 recipe which require .NET 4.5 will throw an exception. Some lines of code reimplementing .NET activation have been removed. --- README.md | 4 +--- metadata.rb | 4 +--- recipes/powershell2.rb | 38 ++++++++++---------------------------- recipes/powershell3.rb | 12 +++++++----- recipes/powershell4.rb | 13 ++++++++----- recipes/powershell5.rb | 9 +++------ 6 files changed, 30 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index df3653d..e6ad4a9 100644 --- a/README.md +++ b/README.md @@ -72,9 +72,7 @@ Not every version of Windows supports every version of Powershell. The following PowerShell also requires the appropriate version of the Microsoft .NET Framework to be installed, if the operating system does not ship with that version. The following community cookbooks are used to install the correct version of the .NET Framework: -* ms_dotnet2 -* ms_dotnet4 -* ms_dotnet45 +* ms_dotnet Resource/Provider ----------------- diff --git a/metadata.rb b/metadata.rb index 4fd47d7..9567c28 100644 --- a/metadata.rb +++ b/metadata.rb @@ -16,9 +16,7 @@ supports 'windows' depends 'windows', '>= 1.2.8' -depends 'ms_dotnet45' -depends 'ms_dotnet4' -depends 'ms_dotnet2' +depends 'ms_dotnet', '>= 2.6' depends 'chef_handler' source_url 'https://github.com/chef-cookbooks/powershell' if respond_to?(:source_url) diff --git a/recipes/powershell2.rb b/recipes/powershell2.rb index 7c5fef0..5a0ed1b 100644 --- a/recipes/powershell2.rb +++ b/recipes/powershell2.rb @@ -23,44 +23,26 @@ case node['platform'] when 'windows' + nt_version = ::Windows::VersionHelper.nt_version(node) - require 'chef/win32/version' - windows_version = Chef::ReservedNames::Win32::Version.new + include_recipe 'ms_dotnet::ms_dotnet2' - if (windows_version.windows_server_2012? || windows_version.windows_8?) && windows_version.core? - # Windows Server 2012 Core does not come with Powershell 2.0 enabled + if nt_version.between?(6.1, 6.2) && ::Windows::VersionHelper.core_version?(node) + feature_suffix = 'V2' if nt_version == 6.2 - windows_feature 'MicrosoftWindowsPowerShellV2' do + windows_feature "MicrosoftWindowsPowerShell#{feature_suffix}" do action :install end - windows_feature 'MicrosoftWindowsPowerShellV2-WOW64' do - action :install - only_if { node['kernel']['machine'] == 'x86_64' } - end - - elsif (windows_version.windows_server_2008_r2? || windows_version.windows_7?) && windows_version.core? - # Windows Server 2008 R2 Core does not come with .NET or Powershell 2.0 enabled - windows_feature 'NetFx2-ServerCore' do - action :install - end - windows_feature 'NetFx2-ServerCore-WOW64' do + windows_feature "MicrosoftWindowsPowerShell#{feature_suffix}-WOW64" do action :install only_if { node['kernel']['machine'] == 'x86_64' } end - windows_feature 'MicrosoftWindowsPowerShell' do - action :install - end - windows_feature 'MicrosoftWindowsPowerShell-WOW64' do - action :install - only_if { node['kernel']['machine'] == 'x86_64' } - end - - elsif windows_version.windows_server_2008? || windows_version.windows_server_2003_r2? || - windows_version.windows_server_2003? || windows_version.windows_xp? - - include_recipe 'ms_dotnet2' + # WMF 2.0 is required and only compatible with: + # * Windows NT 5.1 & 5.2 (Windows Server 2003 & Windows XP) + # * Windows NT 6.0 server (Windows Server 2008 SP2 not vista) + elsif nt_version.between?(5.1, 5.2) || (nt_version == 6.0 && ::Windows::VersionHelper.server_version?(node)) # Reboot if user specifies doesn't specify no_reboot include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' diff --git a/recipes/powershell3.rb b/recipes/powershell3.rb index b1786a4..5b6e921 100644 --- a/recipes/powershell3.rb +++ b/recipes/powershell3.rb @@ -24,13 +24,15 @@ case node['platform'] when 'windows' - require 'chef/win32/version' - windows_version = Chef::ReservedNames::Win32::Version.new + nt_version = ::Windows::VersionHelper.nt_version(node) - if windows_version.windows_server_2008? || windows_version.windows_server_2008_r2? || windows_version.windows_7? + # Powershell 3.0 is only compatible with: + # * Windows NT 6.0 server (Windows Server 2008 SP2 not vista) + # * Windows NT 6.1 (Windows Server 2008R2 & Windows 7.1) + if (nt_version == 6.0 && ::Windows::VersionHelper.server_version?(node)) || nt_version == 6.1 # For Windows Server 2008 ensure that Powershell 2 is already installed and so is BITS 4.0 - if windows_version.windows_server_2008? + if nt_version == 6.0 && ::Windows::VersionHelper.server_version?(node) include_recipe 'powershell::powershell2' windows_package 'Windows Management Framework Bits' do @@ -43,7 +45,7 @@ end # WMF 3.0 requires .NET 4.0 - include_recipe 'ms_dotnet4' + include_recipe 'ms_dotnet::ms_dotnet4' # Reboot if user specifies doesn't specify no_reboot include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' diff --git a/recipes/powershell4.rb b/recipes/powershell4.rb index a9008a2..ade4ee2 100644 --- a/recipes/powershell4.rb +++ b/recipes/powershell4.rb @@ -22,13 +22,16 @@ # http://www.microsoft.com/en-us/download/details.aspx?id=40855 if node['platform'] == 'windows' - require 'chef/win32/version' - windows_version = Chef::ReservedNames::Win32::Version.new - if windows_version.windows_server_2008_r2? || windows_version.windows_7? || windows_version.windows_server_2012? + nt_version = ::Windows::VersionHelper.nt_version(node) + # WMF 4.0 is only compatible with: + # * Windows NT 6.1 (Windows Server 2008R2 & Windows 7.1) + # * Windows NT 6.2 Server (Windows Server 2012 not Windows 8) + if nt_version == 6.1 || (nt_version == 6.2 && ::Windows::VersionHelper.server_version?(node)) - # Ensure .NET 4.5 is installed or installation will fail silently per Microsoft. Only necessary for Windows 2008R2 or 7. - include_recipe 'ms_dotnet45' if windows_version.windows_server_2008_r2? || windows_version.windows_7? + # Ensure .NET 4.5 is installed or installation will fail silently per Microsoft. + fail 'Attribute ms_dotnet.v4.version is not configured to install .NET4.5 as required for Powershell4' if node['ms_dotnet']['v4']['version'] < '4.5' + include_recipe 'ms_dotnet::ms_dotnet4' # Reboot if user specifies doesn't specify no_reboot include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' diff --git a/recipes/powershell5.rb b/recipes/powershell5.rb index 2ccda0f..2d8e758 100644 --- a/recipes/powershell5.rb +++ b/recipes/powershell5.rb @@ -21,15 +21,12 @@ # PowerShell 5.0 Preview Download Page # http://www.microsoft.com/en-us/download/details.aspx?id=42316 -include_recipe 'powershell::powershell2' - case node['platform'] when 'windows' - require 'chef/win32/version' - windows_version = Chef::ReservedNames::Win32::Version.new - - if windows_version.windows_server_2012_r2? || windows_version.windows_8_1? + # Handle WMFC install on 2012R2 and 8.1 only (yet) + if ::Windows::VersionHelper.nt_version(node) == 6.3 + include_recipe 'powershell::powershell2' include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' From c4db2d6bbcb639781070c60667d03001977756ce Mon Sep 17 00:00:00 2001 From: Baptiste Courtois Date: Sat, 28 Nov 2015 16:11:31 +0100 Subject: [PATCH 03/14] Fix rubocop violations * Ignore foodcritic rule #009 for windows package success_codes * Refactor winrm recipe's if statements to remove one nested block * Fix `NoMethodError: undefined method `empty' for nil:NilClass` when powershell.winrm.thumbprint is nil --- recipes/powershell2.rb | 2 +- recipes/powershell3.rb | 2 +- recipes/powershell4.rb | 2 +- recipes/powershell5.rb | 2 +- recipes/winrm.rb | 16 +++++++--------- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/recipes/powershell2.rb b/recipes/powershell2.rb index 5a0ed1b..5914e51 100644 --- a/recipes/powershell2.rb +++ b/recipes/powershell2.rb @@ -46,7 +46,7 @@ # Reboot if user specifies doesn't specify no_reboot include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' - windows_package 'Windows Management Framework Core' do + windows_package 'Windows Management Framework Core' do # ~FC009 source node['powershell']['powershell2']['url'] checksum node['powershell']['powershell2']['checksum'] installer_type :custom diff --git a/recipes/powershell3.rb b/recipes/powershell3.rb index 5b6e921..ed983b2 100644 --- a/recipes/powershell3.rb +++ b/recipes/powershell3.rb @@ -50,7 +50,7 @@ # Reboot if user specifies doesn't specify no_reboot include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' - windows_package 'Windows Management Framework Core 3.0' do + windows_package 'Windows Management Framework Core 3.0' do # ~FC009 source node['powershell']['powershell3']['url'] checksum node['powershell']['powershell3']['checksum'] installer_type :custom diff --git a/recipes/powershell4.rb b/recipes/powershell4.rb index ade4ee2..4e2915e 100644 --- a/recipes/powershell4.rb +++ b/recipes/powershell4.rb @@ -36,7 +36,7 @@ # Reboot if user specifies doesn't specify no_reboot include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' - windows_package 'Windows Management Framework Core4.0' do + windows_package 'Windows Management Framework Core 4.0' do # ~FC009 source node['powershell']['powershell4']['url'] checksum node['powershell']['powershell4']['checksum'] installer_type :custom diff --git a/recipes/powershell5.rb b/recipes/powershell5.rb index 2d8e758..c5a643a 100644 --- a/recipes/powershell5.rb +++ b/recipes/powershell5.rb @@ -30,7 +30,7 @@ include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' - windows_package 'Windows Management Framework Core 5.0' do + windows_package 'Windows Management Framework Core 5.0' do # ~FC009 source node['powershell']['powershell5']['url'] checksum node['powershell']['powershell5']['checksum'] installer_type :custom diff --git a/recipes/winrm.rb b/recipes/winrm.rb index 1b7875e..9ff973b 100644 --- a/recipes/winrm.rb +++ b/recipes/winrm.rb @@ -34,15 +34,13 @@ shell_out = Mixlib::ShellOut.new(winrm_cmd) shell_out.run_command - if !shell_out.stdout.include? 'Transport = HTTPS' - # Create HTTPS listener - if node['powershell']['winrm']['enable_https_transport'] - if node['powershell']['winrm']['thumbprint'].empty? || node['powershell']['winrm']['thumbprint'].nil? - Chef::Log.error('Please specify thumbprint in default attributes for enabling https transport.') - else - powershell_script 'winrm-create-https-listener' do - code "winrm create 'winrm/config/Listener?Address=*+Transport=HTTPS' '@{Hostname=\"#{node['powershell']['winrm']['hostname']}\"; CertificateThumbprint=\"#{node['powershell']['winrm']['thumbprint']}\"}'" - end + # Create HTTPS listener + if !shell_out.stdout.include?('Transport = HTTPS') && node['powershell']['winrm']['enable_https_transport'] + if node['powershell']['winrm']['thumbprint'].nil? || node['powershell']['winrm']['thumbprint'].empty? + Chef::Log.error('Please specify thumbprint in default attributes for enabling https transport.') + else + powershell_script 'winrm-create-https-listener' do + code "winrm create 'winrm/config/Listener?Address=*+Transport=HTTPS' '@{Hostname=\"#{node['powershell']['winrm']['hostname']}\"; CertificateThumbprint=\"#{node['powershell']['winrm']['thumbprint']}\"}'" end end else From 2e9ecc8d775e1108e3388478be6c4859907277d1 Mon Sep 17 00:00:00 2001 From: Baptiste Courtois Date: Sat, 28 Nov 2015 17:06:26 +0100 Subject: [PATCH 04/14] Fix specs for powershell recipes * Update powershell's recipes' specs to test the new code. * Removed useless tests - e.g. windows 7 Core does not exist. * Tests factorization to avoid code/mistake duplication. --- spec/recipes/powershell2_spec.rb | 96 ++++------ spec/recipes/powershell3_spec.rb | 133 ++++++-------- spec/recipes/powershell4_spec.rb | 296 ++++++------------------------- spec/recipes/powershell5_spec.rb | 65 +++---- 4 files changed, 172 insertions(+), 418 deletions(-) diff --git a/spec/recipes/powershell2_spec.rb b/spec/recipes/powershell2_spec.rb index d008b23..dccf35f 100644 --- a/spec/recipes/powershell2_spec.rb +++ b/spec/recipes/powershell2_spec.rb @@ -1,18 +1,11 @@ require 'spec_helper' -require 'chef/win32/version' describe 'powershell::powershell2' do - let(:chef_run) do - ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| - node.set['powershell']['powershell2']['url'] = 'https://powershelltest.com' - node.set['powershell']['powershell2']['checksum'] = '12345' - end.converge(described_recipe) - end - - context 'when windows_version is windows_server_2012 and windows_version is core ' do - before do - @windows_version = double(windows_server_2012?: true, windows_8?: false, core?: true) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) + context 'on Windows Server 2012 Core' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| + node.automatic['kernel']['os_info']['operating_system_sku'] = 0x0D + end.converge(described_recipe) end it 'installs windows features' do @@ -21,25 +14,14 @@ end end - context 'when windows_version is windows_8 and windows_version is core ' do - before do - @windows_version = double(windows_server_2012?: false, windows_8?: true, core?: true) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) + context 'on Windows Server 2008R2 Core' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: '2008R2') do |node| + node.automatic['kernel']['os_info']['operating_system_sku'] = 0x0D + end.converge(described_recipe) end it 'installs windows features' do - expect(chef_run).to install_windows_feature('MicrosoftWindowsPowerShellV2') - expect(chef_run).to install_windows_feature('MicrosoftWindowsPowerShellV2-WOW64') - end - end - - context 'when windows_version is windows_server_2008_r2 and windows_version is core ' do - before do - @windows_version = double(windows_server_2008_r2?: true, windows_7?: false, core?: true, windows_server_2012?: false, windows_8?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - end - - it 'installs windows feature' do expect(chef_run).to install_windows_feature('NetFx2-ServerCore') expect(chef_run).to install_windows_feature('NetFx2-ServerCore-WOW64') expect(chef_run).to install_windows_feature('MicrosoftWindowsPowerShell') @@ -47,46 +29,36 @@ end end - context 'when windows_version is windows_7 and windows_version is core' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: true, core?: true, windows_server_2012?: false, windows_8?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) + context 'on Windows Server 2008' do + let(:chef_run) do + # There is no fauxhai info for windows server 2008, so we use 2008R2 and change the platform version + ChefSpec::SoloRunner.new(platform: 'windows', version: '2008R2') do |node| + node.automatic['platform_version'] = '6.0.6001' + node.set['powershell']['powershell2']['url'] = 'https://powershelltest.com' + node.set['powershell']['powershell2']['checksum'] = '12345' + end.converge(described_recipe) end - it 'installs windows feature' do - expect(chef_run).to install_windows_feature('NetFx2-ServerCore') - expect(chef_run).to install_windows_feature('NetFx2-ServerCore-WOW64') - expect(chef_run).to install_windows_feature('MicrosoftWindowsPowerShell') - expect(chef_run).to install_windows_feature('MicrosoftWindowsPowerShell-WOW64') - end - end + context 'when powershell2 does not exist' do + before do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: false, value_exists?: false, key_exists?: false) + end - context 'when windows_version is windows_server_2008' do - before do - @windows_version = double(windows_server_2008?: true, windows_server_2003_r2?: false, windows_server_2003?: false, windows_xp?: false, windows_server_2008_r2?: false, windows_7?: false, core?: false, windows_server_2012?: false, windows_8?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) + it 'installs windows package' do + expect(chef_run).to include_recipe('ms_dotnet::ms_dotnet2') + expect(chef_run).to install_windows_package('Windows Management Framework Core').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') + end end - it 'installs windows package when powershell2 doesnot exist' do - expect(chef_run).to include_recipe('ms_dotnet2') - expect(chef_run).to install_windows_package('Windows Management Framework Core').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') - end - end - - context 'when windows_version is windows_server_2008' do - before do - @windows_version = double(windows_server_2008?: true, windows_server_2003_r2?: false, windows_server_2003?: false, windows_xp?: false, windows_server_2008_r2?: false, windows_7?: false, core?: false, windows_server_2012?: false, windows_8?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end + context 'when powershell2 exist' do + before do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: true, value_exists?: true) + end - it 'only includes ms_dotnet2 when powershell2 exist' do - expect(chef_run).to include_recipe('ms_dotnet2') + it 'only includes ms_dotnet2' do + expect(chef_run).to include_recipe('ms_dotnet::ms_dotnet2') + expect(chef_run).to_not install_windows_package('Windows Management Framework Core') + end end end end diff --git a/spec/recipes/powershell3_spec.rb b/spec/recipes/powershell3_spec.rb index 095a145..5fa5d2a 100644 --- a/spec/recipes/powershell3_spec.rb +++ b/spec/recipes/powershell3_spec.rb @@ -1,87 +1,58 @@ require 'spec_helper' -require 'chef/win32/version' describe 'powershell::powershell3' do - let(:chef_run) do - ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| - node.set['powershell']['powershell3']['url'] = 'https://powershelltest.com' - node.set['powershell']['powershell3']['checksum'] = '12345' - node.set['powershell']['bits_4']['url'] = 'https://powershellbits.com' - node.set['powershell']['bits_4']['checksum'] = '99999' - end.converge(described_recipe) - end - - context 'when windows_version is windows_server_2008' do - before do - @windows_version = double(windows_server_2008?: true, windows_server_2008_r2?: false, windows_7?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).and_return(true) - end - - it 'installs windows package windows managemet framework bits and windows management framework core 3.0' do - expect(chef_run).to install_windows_package('Windows Management Framework Bits').with(source: 'https://powershellbits.com', checksum: '99999', installer_type: :custom, options: '/quiet /norestart') - expect(chef_run).to install_windows_package('Windows Management Framework Core 3.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') - end - end - - context 'when windows_version is windows_server_2008_r2' do - before do - @windows_version = double(windows_server_2008?: false, windows_server_2008_r2?: true, windows_7?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end - - it 'only include ms_dotnet4 when powershell 3 is installed' do - expect(chef_run).to include_recipe('ms_dotnet4') - end - end - - context 'when windows_version is windows_server_2008_r2' do - before do - @windows_version = double(windows_server_2008?: false, windows_server_2008_r2?: true, windows_7?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows management framework core 3.0 when powershell 3 doesnot exist' do - expect(chef_run).to include_recipe('ms_dotnet4') - expect(chef_run).to install_windows_package('Windows Management Framework Core 3.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') - end - end - - context 'when windows_version is windows_7' do - before do - @windows_version = double(windows_server_2008?: false, windows_server_2008_r2?: false, windows_7?: true) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end - - it 'only include ms_dotnet4 when powershell 3 is installed' do - expect(chef_run).to include_recipe('ms_dotnet4') - end - end - - context 'when windows_version is windows_7' do - before do - @windows_version = double(windows_server_2008?: false, windows_server_2008_r2?: false, windows_7?: true) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows management framework core 3.0 when powershell 3 doesnot exist' do - expect(chef_run).to include_recipe('ms_dotnet4') - expect(chef_run).to install_windows_package('Windows Management Framework Core 3.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') + { + 'Windows Server 2008R2' => { fauxhai_version: '2008R2', should_install_bits: false }, + # There is no fauxhai info for windows server 2008, so we use 2008R2 and change the platform version + 'Windows Server 2008' => { fauxhai_version: '2008R2', platform_version: '6.0.6001', should_install_bits: true }, + # There is no fauxhai info for windows 7, so we use 2008R2 and change the product type from server to workstation + 'Windows 7' => { fauxhai_version: '2008R2', product_type: 1, should_install_bits: false } + }.each do |windows_version, test_conf| + context "on #{windows_version}" do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: test_conf[:fauxhai_version]) do |node| + node.automatic['platform_version'] = test_conf[:platform_version] if test_conf[:platform_version] + node.automatic['kernel']['os_info']['product_type'] = test_conf[:product_type] if test_conf[:product_type] + node.set['powershell']['powershell3']['url'] = 'https://powershelltest.com' + node.set['powershell']['powershell3']['checksum'] = '12345' + node.set['powershell']['bits_4']['url'] = 'https://powershellbits.com' + node.set['powershell']['bits_4']['checksum'] = '99999' + end.converge(described_recipe) + end + + if test_conf[:should_install_bits] + it 'installs windows package Windows Management Framework Bits' do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: true, value_exists?: true) + expect(chef_run).to install_windows_package('Windows Management Framework Bits').with(source: 'https://powershellbits.com', checksum: '99999', installer_type: :custom, options: '/quiet /norestart') + end + else + it 'does not install windows package Windows Management Framework Bits' do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: true, value_exists?: true) + expect(chef_run).to_not install_windows_package('Windows Management Framework Bits') + end + end + + context 'when powershell 3 is installed' do + before do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: true, value_exists?: true) + end + + it 'only include ms_dotnet4' do + expect(chef_run).to include_recipe('ms_dotnet::ms_dotnet4') + expect(chef_run).to_not install_windows_package('Windows Management Framework Core 3.0') + end + end + + context 'when powershell 3 does not exist' do + before do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: false, value_exists?: false, key_exists?: false) + end + + it 'installs windows package windows management framework core 3.0' do + expect(chef_run).to include_recipe('ms_dotnet::ms_dotnet4') + expect(chef_run).to install_windows_package('Windows Management Framework Core 3.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') + end + end end end end diff --git a/spec/recipes/powershell4_spec.rb b/spec/recipes/powershell4_spec.rb index 7899573..7bece4f 100644 --- a/spec/recipes/powershell4_spec.rb +++ b/spec/recipes/powershell4_spec.rb @@ -1,249 +1,59 @@ require 'spec_helper' -require 'chef/win32/version' describe 'powershell::powershell4' do - context 'when installation_reboot_mode is no_reboot' do - let(:chef_run) do - ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| - node.set['powershell']['powershell4']['url'] = 'https://powershelltest.com' - node.set['powershell']['powershell4']['checksum'] = '12345' - node.set['powershell']['installation_reboot_mode'] = 'no_reboot' - end.converge(described_recipe) - end - - context 'when windows_version is windows_server_2008_r2' do - before do - @windows_version = double(windows_server_2008_r2?: true, windows_7?: false, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end - - it 'only includes ms_dotnet45 when powershell 4 is installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - end - end - - context 'when windows_version is windows_server_2008_r2' do - before do - @windows_version = double(windows_server_2008_r2?: true, windows_7?: false, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0 when powershell 4 is not installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) - end - end - - context 'when windows_version is windows_7' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: true, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end - - it 'only includes ms_dotnet45 when powershell 4 is installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - end - end - - context 'when windows_version is windows_7' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: true, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0 when powershell 4 is not installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) - end - end - - context 'when windows_version is windows_server_2012' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: false, windows_server_2012?: true) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0' do - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) - end - end - end - - context 'when installation_reboot_mode is delayed_reboot' do - let(:chef_run) do - ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| - node.set['powershell']['powershell4']['url'] = 'https://powershelltest.com' - node.set['powershell']['powershell4']['checksum'] = '12345' - node.set['powershell']['installation_reboot_mode'] = 'delayed_reboot' - end.converge(described_recipe) - end - - context 'when windows_version is windows_server_2008_r2' do - before do - @windows_version = double(windows_server_2008_r2?: true, windows_7?: false, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end - - it 'only includes ms_dotnet45 when powershell 4 is installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - end - end - - context 'when windows_version is windows_server_2008_r2' do - before do - @windows_version = double(windows_server_2008_r2?: true, windows_7?: false, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0 when powershell 4 is not installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) - end - end - - context 'when windows_version is windows_7' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: true, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end - - it 'only includes ms_dotnet45 when powershell 4 is installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - end - end - - context 'when windows_version is windows_7' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: true, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0 when powershell 4 is not installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) - end - end - - context 'when windows_version is windows_server_2012' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: false, windows_server_2012?: true) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0' do - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) - end - end - end - - context 'when installation_reboot_mode is immediate_reboot' do - let(:chef_run) do - ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| - node.set['powershell']['powershell4']['url'] = 'https://powershelltest.com' - node.set['powershell']['powershell4']['checksum'] = '12345' - node.set['powershell']['installation_reboot_mode'] = 'immediate_reboot' - end.converge(described_recipe) - end - - context 'when windows_version is windows_server_2008_r2' do - before do - @windows_version = double(windows_server_2008_r2?: true, windows_7?: false, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end - - it 'only includes ms_dotnet45 when powershell 4 is installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - end - end - - context 'when windows_version is windows_server_2008_r2' do - before do - @windows_version = double(windows_server_2008_r2?: true, windows_7?: false, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0 when powershell 4 is not installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) - end - end - - context 'when windows_version is windows_7' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: true, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(true) - end - - it 'only includes ms_dotnet45 when powershell 4 is installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - end - end - - context 'when windows_version is windows_7' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: true, windows_server_2012?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0 when powershell 4 is not installed' do - expect(chef_run).to include_recipe('ms_dotnet45') - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) - end - end - - context 'when windows_version is windows_server_2012' do - before do - @windows_version = double(windows_server_2008_r2?: false, windows_7?: false, windows_server_2012?: true) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end - - it 'installs windows package windows managemet framework core 4.0' do - expect(chef_run).to install_windows_package('Windows Management Framework Core4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) + { + # There is no fauxhai info for windows 7, so we use windows 2008R2 and change the product type from server to workstation + 'Windows 7' => { fauxhai_version: '2008R2', product_type: 1 }, + 'Windows Server 2008R2' => { fauxhai_version: '2008R2' }, + 'Windows Server 2012' => { fauxhai_version: '2012' } + }.each do |windows_version, test_conf| + context "on #{windows_version}" do + let(:normal_attributes) { ::Chef::Node::VividMash.new(double('fake_node').as_null_object) } + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: test_conf[:fauxhai_version]) do |node| + node.automatic['kernel']['os_info']['product_type'] = test_conf[:product_type] if test_conf[:product_type] + normal_attributes.each { |k, v| node.set[k] = v } + end.converge(described_recipe) + end + + context 'when ms_dotnet::ms_dotnet4 is not configured for .NET 4.5' do + before { normal_attributes['ms_dotnet']['v4']['version'] = '4.0' } + it 'fails' do + expect { chef_run }.to raise_error + end + end + + context 'when ms_dotnet::ms_dotnet4 is configured for .NET 4.5' do + before { normal_attributes['ms_dotnet']['v4']['version'] = '4.5' } + + context 'when powershell 4 is installed' do + before do + allow_any_instance_of(::Chef::Resource).to receive(:reboot_pending?).and_return false + expect_any_instance_of(::Chef::Resource).to receive(:registry_data_exists?).with('HKLM\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine', name: 'PowerShellVersion', type: :string, data: '4.0').and_return true + end + it 'includes ms_dotnet::ms_dotnet4' do + expect(chef_run).to include_recipe('ms_dotnet::ms_dotnet4') + end + it 'does not install windows package WMFC 4.0' do + expect(chef_run).to_not install_windows_package('Windows Management Framework Core 4.0') + end + end + + context 'when powershell 4 does not exist' do + before do + normal_attributes['powershell']['powershell4']['url'] = 'https://powershelltest.com' + normal_attributes['powershell']['powershell4']['checksum'] = '12345' + normal_attributes['powershell']['installation_reboot_mode'] = 'no_reboot' + allow_any_instance_of(::Chef::Resource).to receive(:reboot_pending?).and_return false + allow_any_instance_of(::Chef::Resource).to receive(:registry_data_exists?).with('HKLM\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine', name: 'PowerShellVersion', type: :string, data: '4.0').and_return false + end + it 'includes ms_dotnet::ms_dotnet4' do + expect(chef_run).to include_recipe('ms_dotnet::ms_dotnet4') + end + it 'installs windows package WMFC 4.0' do + expect(chef_run).to install_windows_package('Windows Management Framework Core 4.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom) + end + end end end end diff --git a/spec/recipes/powershell5_spec.rb b/spec/recipes/powershell5_spec.rb index b69ef4d..7e83ed9 100644 --- a/spec/recipes/powershell5_spec.rb +++ b/spec/recipes/powershell5_spec.rb @@ -1,43 +1,44 @@ require 'spec_helper' -require 'chef/win32/version' describe 'powershell::powershell5' do - let(:chef_run) do - ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| - node.set['powershell']['powershell5']['url'] = 'https://powershelltest.com' - node.set['powershell']['powershell5']['checksum'] = '12345' - end.converge(described_recipe) - end + { + # There is no fauxhai info for windows 8, so we use windows 2012R2 and change the product type from server to workstation + 'Windows 8.1' => { fauxhai_version: '2012R2', product_type: 1 }, + 'Windows Server 2012R2' => { fauxhai_version: '2012R2' } + }.each do |windows_version, test_conf| + context "on #{windows_version}" do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: test_conf[:fauxhai_version]) do |node| + node.automatic['kernel']['os_info']['product_type'] = test_conf[:product_type] if test_conf[:product_type] + node.set['powershell']['powershell5']['url'] = 'https://powershelltest.com' + node.set['powershell']['powershell5']['checksum'] = '12345' + end.converge(described_recipe) + end - before do - allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::powershell2').and_return(true) - end + it 'includes powershell 2 recipe' do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: false, value_exists?: false, key_exists?: false) + expect(chef_run).to include_recipe('powershell::powershell2') + end - context 'when windows_version is windows_server_2012_r2' do - before do - @windows_version = double(windows_server_2012_r2?: true, windows_8_1?: false) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end + context 'when powershell is installed' do + before do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: true, value_exists?: true) + end - it 'installs windows package windows managemet framework core 5.0 if powershell 5 not installed' do - expect(chef_run).to install_windows_package('Windows Management Framework Core 5.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') - end - end + it 'does not install WMF 5' do + expect(chef_run).to_not install_windows_package('Windows Management Framework Core 5.0') + end + end - context 'when windows_version is windows_8_1' do - before do - @windows_version = double(windows_server_2012_r2?: false, windows_8_1?: true) - allow(Chef::ReservedNames::Win32::Version).to receive(:new).and_return(@windows_version) - registry = double - allow(Chef::Win32::Registry).to receive(:new).and_return(registry) - allow(registry).to receive(:data_exists?).and_return(false) - end + context 'when powershell does not exist' do + before do + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: false, value_exists?: false, key_exists?: false) + end - it 'installs windows package windows managemet framework core 5.0 if powershell not installed' do - expect(chef_run).to install_windows_package('Windows Management Framework Core 5.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') + it 'installs windows package windows management framework core 5.0' do + expect(chef_run).to install_windows_package('Windows Management Framework Core 5.0').with(source: 'https://powershelltest.com', checksum: '12345', installer_type: :custom, options: '/quiet /norestart') + end + end end end end From a7d14e2165ce9f43441ccc61a3bf9db6e9685074 Mon Sep 17 00:00:00 2001 From: Baptiste Courtois Date: Sat, 28 Nov 2015 16:13:59 +0100 Subject: [PATCH 05/14] Fix specs for winrm recipe Update winrm's specs to be able to test on linux/travis: * Remove references to `chef/winr32/version` * Mock shellout commands --- spec/recipes/winrm_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/recipes/winrm_spec.rb b/spec/recipes/winrm_spec.rb index 6bdb490..9f08bc2 100644 --- a/spec/recipes/winrm_spec.rb +++ b/spec/recipes/winrm_spec.rb @@ -1,11 +1,15 @@ require 'spec_helper' -require 'chef/win32/version' describe 'powershell::winrm' do let(:chef_run) do ChefSpec::SoloRunner.new(platform: 'windows', version: '2012').converge(described_recipe) end + before do + winrm_cmd = double('winrm_cmd', run_command: nil, stdout: 'Transport = HTTPS') + allow(Mixlib::ShellOut).to receive(:new).with('powershell.exe winrm enumerate winrm/config/listener').and_return winrm_cmd + end + it 'installs windows package windows managemet framework core 5.0' do expect(chef_run).to run_powershell_script('enable winrm').with(code: " winrm quickconfig -q\n") end From 2d48a00aad4e5c1f51ff2c137d265bce1c864162 Mon Sep 17 00:00:00 2001 From: Baptiste Courtois Date: Sat, 28 Nov 2015 16:14:32 +0100 Subject: [PATCH 06/14] Fix specs for dsc recipe Update dsc's specs to comply with powershell::powershell4 changes. Mock properly shellout commands. --- spec/recipes/dsc_spec.rb | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/spec/recipes/dsc_spec.rb b/spec/recipes/dsc_spec.rb index 8cef16c..053fbf1 100644 --- a/spec/recipes/dsc_spec.rb +++ b/spec/recipes/dsc_spec.rb @@ -2,16 +2,22 @@ require 'mixlib/shellout' describe 'powershell::dsc' do - let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'windows', version: '2012').converge(described_recipe) } + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: '2012')do |node| + node.set['ms_dotnet']['v4']['version'] = '4.5' + end.converge(described_recipe) + end + + before do + winrm_cmd = double('winrm_cmd', run_command: nil, stdout: 'Transport = HTTPS') + allow(Mixlib::ShellOut).to receive(:new).with('powershell.exe winrm enumerate winrm/config/listener').and_return winrm_cmd + allow(Chef::Win32::Registry).to receive(:new).and_return double('registry', data_exists?: false, value_exists?: false, key_exists?: false) + end context 'When listener is enabled' do before do - command = 'powershell.exe winrm get winrm/config/listener?Address=*+Transport=HTTP' - - shell_obj = instance_double('Mixlib::ShellOut') - allow(Mixlib::ShellOut).to receive(:new).with(command).and_return(shell_obj) - allow(shell_obj).to receive(:run_command) - allow(shell_obj).to receive(:exitstatus).and_return(1) + dsc_cmd = double('dsc_cmd', run_command: nil, exitstatus: 1) + allow(Mixlib::ShellOut).to receive(:new).with('powershell.exe winrm get winrm/config/listener?Address=*+Transport=HTTP').and_return dsc_cmd end it 'runs dsc_script' do @@ -22,12 +28,8 @@ context 'When listener is disabled' do before do - command = 'powershell.exe winrm get winrm/config/listener?Address=*+Transport=HTTP' - - shell_obj = instance_double('Mixlib::ShellOut') - allow(Mixlib::ShellOut).to receive(:new).with(command).and_return(shell_obj) - allow(shell_obj).to receive(:run_command) - allow(shell_obj).to receive(:exitstatus).and_return(0) + dsc_cmd = double('dsc_cmd', run_command: nil, exitstatus: 0) + allow(Mixlib::ShellOut).to receive(:new).with('powershell.exe winrm get winrm/config/listener?Address=*+Transport=HTTP').and_return dsc_cmd end it 'runs dsc_script' do From 792771710ddec1c551d396da6a9a74caeb59d1d2 Mon Sep 17 00:00:00 2001 From: Baptiste Courtois Date: Sat, 28 Nov 2015 16:32:46 +0100 Subject: [PATCH 07/14] Fix specs for powershell_module provider Clean up powershell_module provider specs: * Mock file system operations and remove all actual IO from the tests! * Remove use of environment variable Theses tests were relying on the test machine file system: * It was expecting the test machine to be windows with powershell etc. * It was also creating "temporary" files and folders. --- .../powershell_module_provider_spec.rb | 113 ++++++------------ 1 file changed, 38 insertions(+), 75 deletions(-) diff --git a/spec/libraries/powershell_module_provider_spec.rb b/spec/libraries/powershell_module_provider_spec.rb index 768e6d6..bb5862a 100644 --- a/spec/libraries/powershell_module_provider_spec.rb +++ b/spec/libraries/powershell_module_provider_spec.rb @@ -17,14 +17,17 @@ # require_relative '../../libraries/powershell_module_provider' -require 'tmpdir' describe 'PowershellModuleProvider' do before do + allow(Chef::Config).to receive(:[]).with(:file_cache_path).and_return 'C:/tmp' + allow(Chef::Config).to receive(:[]).with(:why_run).and_return false + @node = Chef::Node.new @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) @new_resource = PowershellModule.new('testmodule', @run_context) + @new_resource.destination '/' @provider = PowershellModuleProvider.new(@new_resource, @run_context) end @@ -37,7 +40,7 @@ describe 'action_uninstall:' do it 'uninstall module' do - @provider.should_receive(:uninstall_module) + expect(@provider).to receive(:uninstall_module) expect { @provider.run_action(:uninstall) }.to_not raise_error end end @@ -67,78 +70,51 @@ end describe 'download_extract_module:' do - context 'when download_url and target are nil' do - before do - ENV['PROGRAMW6432'] = 'C:\\PROGRAMW6432' - @ps_cmd = double - end + before do + allow(@provider).to receive(:module_exists?).and_return false + end + context 'when download_url and target are nil' do it 'downloads the package' do - expect(Dir).to receive(:mktmpdir).and_return('C:/tmp/') - cmd_str = "powershell.exe Invoke-WebRequest testmodule -OutFile C:/tmp/testmodule.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('C:\\tmp\\testmodule.zip'); $shell.Namespace('C:\\PROGRAMW6432\\WindowsPowerShell\\Modules').copyhere($zip.items(), 0x14);write-host $shell" - expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(@ps_cmd) - expect(@ps_cmd).to receive(:run_command) + cmd_str = "powershell.exe Invoke-WebRequest testmodule -OutFile C:/tmp/testmodule.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('C:\\tmp\\testmodule.zip'); $shell.Namespace('\\').copyhere($zip.items(), 0x14);write-host $shell" + expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(double('ps_cmd', run_command: nil)) expect(@provider.send(:download_extract_module)).to eq('C:/tmp/testmodule.zip') end end context 'when download_url is provided and target is nil' do - before do - ENV['PROGRAMW6432'] = 'C:\\PROGRAMW6432' - @ps_cmd = double - end - it 'downloads the package' do - expect(Dir).to receive(:mktmpdir).and_return('C:/tmp/') - cmd_str = "powershell.exe Invoke-WebRequest https://temp_download.com -OutFile C:/tmp/testmodule.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('C:\\tmp\\testmodule.zip'); $shell.Namespace('C:\\PROGRAMW6432\\WindowsPowerShell\\Modules').copyhere($zip.items(), 0x14);write-host $shell" - expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(@ps_cmd) - expect(@ps_cmd).to receive(:run_command) + cmd_str = "powershell.exe Invoke-WebRequest https:/temp_download.com -OutFile C:/tmp/testmodule.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('C:\\tmp\\testmodule.zip'); $shell.Namespace('\\').copyhere($zip.items(), 0x14);write-host $shell" + expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(double('ps_cmd', run_command: nil)) - expect(@provider.send(:download_extract_module, 'https://temp_download.com')).to eq('C:/tmp/testmodule.zip') + expect(@provider.send(:download_extract_module, 'https:/temp_download.com')).to eq('C:/tmp/testmodule.zip') end end context 'when download_url is nil and target is provided' do - before do - ENV['PROGRAMW6432'] = 'C:\\PROGRAMW6432' - @ps_cmd = double - end - it 'downloads the package' do - cmd_str = "powershell.exe Invoke-WebRequest testmodule -OutFile tmp/target1.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('tmp\\target1.zip'); $shell.Namespace('C:\\PROGRAMW6432\\WindowsPowerShell\\Modules').copyhere($zip.items(), 0x14);write-host $shell" - expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(@ps_cmd) - expect(@ps_cmd).to receive(:run_command) + cmd_str = "powershell.exe Invoke-WebRequest testmodule -OutFile tmp/target1.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('tmp\\target1.zip'); $shell.Namespace('\\').copyhere($zip.items(), 0x14);write-host $shell" + expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(double('ps_cmd', run_command: nil)) expect(@provider.send(:download_extract_module, nil, 'tmp/target1.zip')).to eq('tmp/target1.zip') end end context 'when download_url and target are provided' do - before do - ENV['PROGRAMW6432'] = 'C:\\PROGRAMW6432' - @ps_cmd = double - end - it 'downloads the package' do - cmd_str = "powershell.exe Invoke-WebRequest https://temp_download.com -OutFile tmp/target1.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('tmp\\target1.zip'); $shell.Namespace('C:\\PROGRAMW6432\\WindowsPowerShell\\Modules').copyhere($zip.items(), 0x14);write-host $shell" - expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(@ps_cmd) - expect(@ps_cmd).to receive(:run_command) + cmd_str = "powershell.exe Invoke-WebRequest https:/temp_download.com -OutFile tmp/target1.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('tmp\\target1.zip'); $shell.Namespace('\\').copyhere($zip.items(), 0x14);write-host $shell" + expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(double('ps_cmd', run_command: nil)) - expect(@provider.send(:download_extract_module, 'https://temp_download.com', 'tmp/target1.zip')).to eq('tmp/target1.zip') + expect(@provider.send(:download_extract_module, 'https:/temp_download.com', 'tmp/target1.zip')).to eq('tmp/target1.zip') end end end describe 'uninstall_module:' do context 'when module directory exists' do - before do - ENV['PROGRAMW6432'] = 'C:/PROGRAMW6432' - @ps_cmd = double - end - it 'uninstalls module' do - module_dir = 'C:/PROGRAMW6432/WindowsPowerShell/Modules/testmodule' + module_dir = '/testmodule' expect(Dir).to receive(:exist?).with(module_dir).and_return(true) expect(FileUtils).to receive(:rm_rf).with(module_dir) expect(Chef::Log).to receive(:info).with("Powershell Module 'testmodule' uninstallation completed successfully") @@ -148,13 +124,8 @@ end context 'when module directory does not exist' do - before do - ENV['PROGRAMW6432'] = 'C:/PROGRAMW6432' - @ps_cmd = double - end - it 'logs message' do - module_dir = 'C:/PROGRAMW6432/WindowsPowerShell/Modules/testmodule' + module_dir = '/testmodule' expect(Dir).to receive(:exist?).with(module_dir).and_return(false) expect(Chef::Log).to receive(:info).with("Unable to locate module 'testmodule'") @@ -164,32 +135,18 @@ end describe 'install_module:' do - before do - ENV['PROGRAMW6432'] = 'C:/PROGRAMW6432' - @ps_cmd = double - end - context 'install from local source' do - before do - @dir = Dir.tmpdir + '/testmodule' - FileUtils.mkdir_p(@dir) unless File.directory?(@dir) - @module_files = ["#{@dir}/test.psd1", "#{@dir}/test.psm1", "#{@dir}/test.dll"] - @module_files.each do |file| - File.new("#{file}", 'w+') - end - end - - after do - FileUtils.rm_rf(@dir) if File.directory?(@dir) - end - it 'copies module from source to ps module path' do - @new_resource.source(@dir) - ps_module_path = 'C:/PROGRAMW6432/WindowsPowerShell/Modules/testmodule' - expect(Dir).to receive(:exist?).with('/tmp/testmodule').and_return(true) + ps_module_path = '/testmodule' + @new_resource.source(ps_module_path) + + module_files = %W(#{ps_module_path}/*.psd1 #{ps_module_path}/*.psm1 #{ps_module_path}/*.dll) + expect(Dir).to receive(:exist?).with(ps_module_path).and_return(true) expect(FileUtils).to receive(:mkdir_p).with(ps_module_path).and_return(["#{ps_module_path}"]) - @module_files.each do |filename| + expect(Dir).to receive(:[]).with(*module_files).and_return module_files + + module_files.each do |filename| expect(FileUtils).to receive(:cp).with(filename, ps_module_path) end @@ -198,9 +155,15 @@ end context 'source is a url' do it 'downloads module from source and install' do - @new_resource.source('https://testmodule.com') - expect(@provider).to receive(:download_extract_module).and_return('C:/tmp/testmodule') - expect(FileUtils).to receive(:rm_rf).with('C:/tmp') + source = 'https:/testmodule.com' + destination = 'C:/tmp/testmodule' + @new_resource.source source + + expect(Dir).to receive(:exist?).with(source).and_return(false) + expect(@provider).to receive(:download_extract_module).and_return(destination) + expect(File).to receive(:exist?).with(destination).and_return(true) + expect(FileUtils).to receive(:rm_f).with(destination) + @provider.send(:install_module) end end From d7894563ca5bf0a5e402d2a8ee5a691139dac279 Mon Sep 17 00:00:00 2001 From: aliasgar16 Date: Thu, 1 Oct 2015 16:55:02 +0530 Subject: [PATCH 08/14] Added LCM configuration recipes. --- attributes/config_lcm.rb | 10 ++++++ recipes/disable_lcm.rb | 63 ++++++++++++++++++++++++++++++++++ recipes/enable_dsc_script.rb | 20 +++++++++++ recipes/enable_lcm.rb | 65 ++++++++++++++++++++++++++++++++++++ recipes/powershell2.rb | 2 +- 5 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 attributes/config_lcm.rb create mode 100644 recipes/disable_lcm.rb create mode 100644 recipes/enable_dsc_script.rb create mode 100644 recipes/enable_lcm.rb diff --git a/attributes/config_lcm.rb b/attributes/config_lcm.rb new file mode 100644 index 0000000..e0f266b --- /dev/null +++ b/attributes/config_lcm.rb @@ -0,0 +1,10 @@ + +## temporary directory related attributes ## +default['lcm']['mof']['temp_dir'] = "#{Chef::Config[:file_cache_path]}\\lcm_mof" + + +## lcm configuration related attributes ## +default['lcm']['config']['enable']['config_mode'] = "ApplyOnly" +default['lcm']['config']['enable']['reboot_node'] = false +default['lcm']['config']['enable']['refresh_mode'] = "Push" +default['lcm']['config']['disable']['refresh_mode'] = "Disabled" diff --git a/recipes/disable_lcm.rb b/recipes/disable_lcm.rb new file mode 100644 index 0000000..d645b81 --- /dev/null +++ b/recipes/disable_lcm.rb @@ -0,0 +1,63 @@ +# +# Author:: Aliasgar Batterywala () +# Cookbook Name:: powershell +# Recipe:: disable_lcm +# +# Copyright:: Copyright (c) 2015 Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include_recipe 'powershell::powershell5' +include_recipe 'powershell::dsc' + +case node['platform'] +when 'windows' + + directory "Creating temporary directory to store LCM MOF files" do + path node['lcm']['mof']['temp_dir'] + rights :read, 'Everyone' + action :create + end + + powershell_script "Disable LCM" do + code <<-EOH + + Configuration DisableLCM + { + Node "localhost" + { + LocalConfigurationManager + { + RefreshMode = "#{node['lcm']['config']['disable']['refresh_mode']}" + } + } + } + + DisableLCM -OutputPath "#{node['lcm']['mof']['temp_dir']}" + + Set-DscLocalConfigurationManager -Path "#{node['lcm']['mof']['temp_dir']}" + EOH + not_if <<-EOH + $LCM = (Get-DscLocalConfigurationManager) + $LCM.RefreshMode -eq "#{node['lcm']['config']['disable']['refresh_mode']}" + EOH + end + + directory "Deleting temporary directory which stored LCM MOF files" do + path node['lcm']['mof']['temp_dir'] + recursive true + action :delete + end +else + Chef::Log.warn('LCM configuration can only be executed on the Windows platform.') +end diff --git a/recipes/enable_dsc_script.rb b/recipes/enable_dsc_script.rb new file mode 100644 index 0000000..966b8e0 --- /dev/null +++ b/recipes/enable_dsc_script.rb @@ -0,0 +1,20 @@ +# +# Author:: Aliasgar Batterywala () +# Cookbook Name:: powershell +# Recipe:: enable_lcm +# +# Copyright:: Copyright (c) 2015 Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include_recipe 'powershell::enable_lcm' diff --git a/recipes/enable_lcm.rb b/recipes/enable_lcm.rb new file mode 100644 index 0000000..57e8a7f --- /dev/null +++ b/recipes/enable_lcm.rb @@ -0,0 +1,65 @@ +# +# Author:: Aliasgar Batterywala () +# Cookbook Name:: powershell +# Recipe:: enable_lcm +# +# Copyright:: Copyright (c) 2015 Chef Software, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include_recipe 'powershell::dsc' + +case node['platform'] +when 'windows' + + directory "Creating temporary directory to store LCM MOF files" do + path node['lcm']['mof']['temp_dir'] + rights :read, 'Everyone' + action :create + end + + powershell_script "Configure and Enable LCM" do + code <<-EOH + + Configuration EnableLCM + { + Node "localhost" + { + LocalConfigurationManager + { + ConfigurationMode = "#{node['lcm']['config']['enable']['config_mode']}" + RebootNodeIfNeeded = $#{node['lcm']['config']['enable']['reboot_node']} + RefreshMode = "#{node['lcm']['config']['enable']['refresh_mode']}" + } + } + } + + EnableLCM -OutputPath "#{node['lcm']['mof']['temp_dir']}" + + Set-DscLocalConfigurationManager -Path "#{node['lcm']['mof']['temp_dir']}" + EOH + not_if <<-EOH + $LCM = (Get-DscLocalConfigurationManager) + $LCM.ConfigurationMode -eq "#{node['lcm']['config']['enable']['config_mode']}" -and + $LCM.RefreshMode -eq "#{node['lcm']['config']['enable']['refresh_mode']}" + EOH + end + + directory "Deleting temporary directory which stored LCM MOF files" do + path node['lcm']['mof']['temp_dir'] + recursive true + action :delete + end +else + Chef::Log.warn('LCM configuration can only be executed on the Windows platform.') +end diff --git a/recipes/powershell2.rb b/recipes/powershell2.rb index 5914e51..6468440 100644 --- a/recipes/powershell2.rb +++ b/recipes/powershell2.rb @@ -43,7 +43,7 @@ # * Windows NT 5.1 & 5.2 (Windows Server 2003 & Windows XP) # * Windows NT 6.0 server (Windows Server 2008 SP2 not vista) elsif nt_version.between?(5.1, 5.2) || (nt_version == 6.0 && ::Windows::VersionHelper.server_version?(node)) - # Reboot if user specifies doesn't specify no_reboot + # Reboot if user doesn't specify no_reboot include_recipe 'powershell::windows_reboot' unless node['powershell']['installation_reboot_mode'] == 'no_reboot' windows_package 'Windows Management Framework Core' do # ~FC009 From 0de47d67421c8d747202d6ce653885d764b3722f Mon Sep 17 00:00:00 2001 From: aliasgar16 Date: Mon, 5 Oct 2015 11:59:21 +0530 Subject: [PATCH 09/14] Addes ChefSpecs for LCM config recipes and rectified issues reported by Foodcritic and Rubocop for the same recipes. --- attributes/config_lcm.rb | 7 ++-- recipes/disable_lcm.rb | 6 +-- recipes/enable_lcm.rb | 6 +-- spec/recipes/disable_lcm_spec.rb | 55 +++++++++++++++++++++++++ spec/recipes/enable_dsc_script_spec.rb | 19 +++++++++ spec/recipes/enable_lcm_spec.rb | 57 ++++++++++++++++++++++++++ 6 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 spec/recipes/disable_lcm_spec.rb create mode 100644 spec/recipes/enable_dsc_script_spec.rb create mode 100644 spec/recipes/enable_lcm_spec.rb diff --git a/attributes/config_lcm.rb b/attributes/config_lcm.rb index e0f266b..f6c8a99 100644 --- a/attributes/config_lcm.rb +++ b/attributes/config_lcm.rb @@ -2,9 +2,8 @@ ## temporary directory related attributes ## default['lcm']['mof']['temp_dir'] = "#{Chef::Config[:file_cache_path]}\\lcm_mof" - ## lcm configuration related attributes ## -default['lcm']['config']['enable']['config_mode'] = "ApplyOnly" +default['lcm']['config']['enable']['config_mode'] = 'ApplyOnly' default['lcm']['config']['enable']['reboot_node'] = false -default['lcm']['config']['enable']['refresh_mode'] = "Push" -default['lcm']['config']['disable']['refresh_mode'] = "Disabled" +default['lcm']['config']['enable']['refresh_mode'] = 'Push' +default['lcm']['config']['disable']['refresh_mode'] = 'Disabled' diff --git a/recipes/disable_lcm.rb b/recipes/disable_lcm.rb index d645b81..1ab7fb5 100644 --- a/recipes/disable_lcm.rb +++ b/recipes/disable_lcm.rb @@ -23,13 +23,13 @@ case node['platform'] when 'windows' - directory "Creating temporary directory to store LCM MOF files" do + directory 'Creating temporary directory to store LCM MOF files' do path node['lcm']['mof']['temp_dir'] rights :read, 'Everyone' action :create end - powershell_script "Disable LCM" do + powershell_script 'Disable LCM' do code <<-EOH Configuration DisableLCM @@ -53,7 +53,7 @@ EOH end - directory "Deleting temporary directory which stored LCM MOF files" do + directory 'Deleting temporary directory which stored LCM MOF files' do path node['lcm']['mof']['temp_dir'] recursive true action :delete diff --git a/recipes/enable_lcm.rb b/recipes/enable_lcm.rb index 57e8a7f..ed23baf 100644 --- a/recipes/enable_lcm.rb +++ b/recipes/enable_lcm.rb @@ -22,13 +22,13 @@ case node['platform'] when 'windows' - directory "Creating temporary directory to store LCM MOF files" do + directory 'Creating temporary directory to store LCM MOF files' do path node['lcm']['mof']['temp_dir'] rights :read, 'Everyone' action :create end - powershell_script "Configure and Enable LCM" do + powershell_script 'Configure and Enable LCM' do code <<-EOH Configuration EnableLCM @@ -55,7 +55,7 @@ EOH end - directory "Deleting temporary directory which stored LCM MOF files" do + directory 'Deleting temporary directory which stored LCM MOF files' do path node['lcm']['mof']['temp_dir'] recursive true action :delete diff --git a/spec/recipes/disable_lcm_spec.rb b/spec/recipes/disable_lcm_spec.rb new file mode 100644 index 0000000..37000d2 --- /dev/null +++ b/spec/recipes/disable_lcm_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' +require 'chefspec' + +describe 'powershell::disable_lcm' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| + node.set['powershell']['powershell5']['url'] = 'https://powershelltest.com' + node.set['powershell']['powershell5']['checksum'] = '12345' + node.set['lcm']['mof']['temp_dir'] = 'c:\\chef\\cache\\lcm_mof' + node.set['lcm']['config']['disable']['refresh_mode'] = 'Disabled' + end.converge(described_recipe) + end + + before do + @config_code = <<-EOH + + Configuration DisableLCM + { + Node "localhost" + { + LocalConfigurationManager + { + RefreshMode = "Disabled" + } + } + } + + DisableLCM -OutputPath "c:\\chef\\cache\\lcm_mof" + + Set-DscLocalConfigurationManager -Path "c:\\chef\\cache\\lcm_mof" + EOH + + guard_condition = <<-EOH + $LCM = (Get-DscLocalConfigurationManager) + $LCM.RefreshMode -eq "Disabled" + EOH + stub_command(guard_condition).and_return(false) + + allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::powershell5').and_return(true) + allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::dsc').and_return(true) + end + + it 'disables LCM' do + expect(chef_run).to create_directory('Creating temporary directory to store LCM MOF files').with( + path: 'c:\\chef\\cache\\lcm_mof' + ) + expect(chef_run).to run_powershell_script('Disable LCM').with( + code: @config_code + ) + expect(chef_run).to delete_directory('Deleting temporary directory which stored LCM MOF files').with( + path: 'c:\\chef\\cache\\lcm_mof', + recursive: true + ) + end +end diff --git a/spec/recipes/enable_dsc_script_spec.rb b/spec/recipes/enable_dsc_script_spec.rb new file mode 100644 index 0000000..9b30b70 --- /dev/null +++ b/spec/recipes/enable_dsc_script_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' +require 'chefspec' + +describe 'powershell::enable_dsc_script' do + let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'windows', version: '2012').converge(described_recipe) } + + before do + guard_condition = <<-EOH + $LCM = (Get-DscLocalConfigurationManager) + $LCM.ConfigurationMode -eq "ApplyOnly" -and + $LCM.RefreshMode -eq "Push" + EOH + stub_command(guard_condition).and_return(false) + end + + it 'includes enable_lcm recipe' do + expect(chef_run).to include_recipe('powershell::enable_lcm') + end +end diff --git a/spec/recipes/enable_lcm_spec.rb b/spec/recipes/enable_lcm_spec.rb new file mode 100644 index 0000000..c74a0f3 --- /dev/null +++ b/spec/recipes/enable_lcm_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' +require 'chefspec' + +describe 'powershell::enable_lcm' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| + node.set['lcm']['mof']['temp_dir'] = 'c:\\chef\\cache\\lcm_mof' + node.set['lcm']['config']['enable']['config_mode'] = 'ApplyOnly' + node.set['lcm']['config']['enable']['reboot_node'] = false + node.set['lcm']['config']['enable']['refresh_mode'] = 'Push' + end.converge(described_recipe) + end + + before do + @config_code = <<-EOH + + Configuration EnableLCM + { + Node "localhost" + { + LocalConfigurationManager + { + ConfigurationMode = "ApplyOnly" + RebootNodeIfNeeded = $false + RefreshMode = "Push" + } + } + } + + EnableLCM -OutputPath "c:\\chef\\cache\\lcm_mof" + + Set-DscLocalConfigurationManager -Path "c:\\chef\\cache\\lcm_mof" + EOH + + guard_condition = <<-EOH + $LCM = (Get-DscLocalConfigurationManager) + $LCM.ConfigurationMode -eq "ApplyOnly" -and + $LCM.RefreshMode -eq "Push" + EOH + stub_command(guard_condition).and_return(false) + + allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::dsc').and_return(true) + end + + it 'enables LCM' do + expect(chef_run).to create_directory('Creating temporary directory to store LCM MOF files').with( + path: 'c:\\chef\\cache\\lcm_mof' + ) + expect(chef_run).to run_powershell_script('Configure and Enable LCM').with( + code: @config_code + ) + expect(chef_run).to delete_directory('Deleting temporary directory which stored LCM MOF files').with( + path: 'c:\\chef\\cache\\lcm_mof', + recursive: true + ) + end +end From e217e28f3a38472b3591abb59cdca8c69b4ac054 Mon Sep 17 00:00:00 2001 From: Steven Murawski Date: Fri, 4 Dec 2015 15:32:44 -0600 Subject: [PATCH 10/14] make enable_lcm only create and delete directories when required --- recipes/enable_lcm.rb | 18 +++++++++++++----- spec/recipes/enable_dsc_script_spec.rb | 6 +++++- spec/recipes/enable_lcm_spec.rb | 8 ++++---- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/recipes/enable_lcm.rb b/recipes/enable_lcm.rb index ed23baf..b409360 100644 --- a/recipes/enable_lcm.rb +++ b/recipes/enable_lcm.rb @@ -26,6 +26,18 @@ path node['lcm']['mof']['temp_dir'] rights :read, 'Everyone' action :create + guard_interpreter :powershell_script + not_if <<-EOH + $LCM = (Get-DscLocalConfigurationManager) + $LCM.ConfigurationMode -eq "#{node['lcm']['config']['enable']['config_mode']}" -and + $LCM.RefreshMode -eq "#{node['lcm']['config']['enable']['refresh_mode']}" + EOH + end + + directory 'Deleting temporary directory which stored LCM MOF files' do + path node['lcm']['mof']['temp_dir'] + recursive true + action :nothing end powershell_script 'Configure and Enable LCM' do @@ -53,13 +65,9 @@ $LCM.ConfigurationMode -eq "#{node['lcm']['config']['enable']['config_mode']}" -and $LCM.RefreshMode -eq "#{node['lcm']['config']['enable']['refresh_mode']}" EOH + notifies :delete, 'directory[Deleting temporary directory which stored LCM MOF files]', :immediately end - directory 'Deleting temporary directory which stored LCM MOF files' do - path node['lcm']['mof']['temp_dir'] - recursive true - action :delete - end else Chef::Log.warn('LCM configuration can only be executed on the Windows platform.') end diff --git a/spec/recipes/enable_dsc_script_spec.rb b/spec/recipes/enable_dsc_script_spec.rb index 9b30b70..823ae4a 100644 --- a/spec/recipes/enable_dsc_script_spec.rb +++ b/spec/recipes/enable_dsc_script_spec.rb @@ -2,7 +2,11 @@ require 'chefspec' describe 'powershell::enable_dsc_script' do - let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'windows', version: '2012').converge(described_recipe) } + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| + node.set['ms_dotnet']['v4']['version'] = '4.5' + end.converge(described_recipe) + end before do guard_condition = <<-EOH diff --git a/spec/recipes/enable_lcm_spec.rb b/spec/recipes/enable_lcm_spec.rb index c74a0f3..cd4650e 100644 --- a/spec/recipes/enable_lcm_spec.rb +++ b/spec/recipes/enable_lcm_spec.rb @@ -49,9 +49,9 @@ expect(chef_run).to run_powershell_script('Configure and Enable LCM').with( code: @config_code ) - expect(chef_run).to delete_directory('Deleting temporary directory which stored LCM MOF files').with( - path: 'c:\\chef\\cache\\lcm_mof', - recursive: true - ) + expect(chef_run.powershell_script('Configure and Enable LCM')) + .to notify('directory[Deleting temporary directory which stored LCM MOF files]') + .to(:delete) + .immediately end end From bada2c4de96ba9a082ce9f538aab71a1a3e0a0b4 Mon Sep 17 00:00:00 2001 From: Steven Murawski Date: Fri, 4 Dec 2015 17:07:11 -0600 Subject: [PATCH 11/14] updated CHANGELOG, README and metadata in prep for a 3.2.0 release. Still need to do some manual testing. --- CHANGELOG.md | 9 +++++++++ README.md | 2 +- metadata.rb | 6 ++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bebceb2..648fccc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ powershell Cookbook CHANGELOG ============================= This file is used to list changes made in each version of the powershell cookbook. +v3.2.0 (unreleased) +------------------- +- [**Annih**](https://github.com/Annih) + [PR #61](http://github.com/chef-cookbooks/powershell/pull/61) - use the all in one ms_dotnet cookbook +- [**RyanJarv**](https://github.com/RyanJarv) + [PR #60](http://github.com/chef-cookbooks/powershell/pull/60) - Use Ruby to unzip to support 2008 R2 Server Core +- [**Aliasgar16**](https://Aliasgar16) + [PR #57](http://github.com/chef-cookbooks/powershell/pull/57) - Add LCM configuration recipes + v3.1.0 (2015-04-27) ------------------- - [**webframp**](https://github.com/webframp) diff --git a/README.md b/README.md index 6103f2f..dac520d 100644 --- a/README.md +++ b/README.md @@ -232,7 +232,7 @@ Usage ### default -The default recipe is needs to be included before using the powershell_module recipe. +The default recipe is needs to be included before using the powershell_module resource. ### powershell2 diff --git a/metadata.rb b/metadata.rb index 9567c28..e6f352f 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,15 +4,17 @@ license 'Apache 2.0' description 'Installs/Configures PowerShell on the Windows platform' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '3.1.0' +version '3.2.0' -recipe 'powershell::default', 'Does nothing; choose the right version of Powershell by selecting the correct recipe' +recipe 'powershell::default', 'Makes sure RubyZip is installed (for powershell_module)' recipe 'powershell::powershell2', 'Installs PowerShell 2.0' recipe 'powershell::powershell3', 'Installs PowerShell 3.0' recipe 'powershell::powershell4', 'Installs PowerShell 4.0' recipe 'powershell::powershell5', 'Installs PowerShell 5.0' recipe 'powershell::winrm', 'Configures WinRM' recipe 'powershell::dsc', 'Desired State Configuration' +recipe 'powershell::enable_lcm', 'Enable the DSC Local Configuration Manager' +recipe 'powershell::disable_lcm', 'Disable the DSC Local Configuration Manager' supports 'windows' depends 'windows', '>= 1.2.8' From 93ae7e5e29ae4fec48a08af44eaf8a6b06e8df9f Mon Sep 17 00:00:00 2001 From: Steven Murawski Date: Fri, 4 Dec 2015 17:45:43 -0600 Subject: [PATCH 12/14] fix up tests for powershell_module after moving to rubyzip --- libraries/powershell_module_provider.rb | 16 +++++----- .../powershell_module_provider_spec.rb | 29 +++++++------------ 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/libraries/powershell_module_provider.rb b/libraries/powershell_module_provider.rb index 145996b..e804867 100644 --- a/libraries/powershell_module_provider.rb +++ b/libraries/powershell_module_provider.rb @@ -65,13 +65,7 @@ def install_module FileUtils.cp(filename, ps_module_path) end elsif @new_resource.source =~ URI.regexp # Check for valid URL - downloaded_file = download_extract_module - - if ::File.exist?(downloaded_file) - Chef::Log.debug("Powershell Module '#{@powershell_module.package_name}' removing download #{downloaded_file}") - FileUtils.rm_f(downloaded_file) - end - + download_extract_module end end @@ -141,9 +135,15 @@ def download_extract_module(download_url = nil, target = nil) else download(download_url, target) unzip(target, ps_module_path) + remove_download(target) end + end - target + def remove_download(target) + if ::File.exist?(target) + Chef::Log.debug("Powershell Module '#{@powershell_module.package_name}' removing download #{downloaded_file}") + FileUtils.rm_f(downloaded_file) + end end def module_path_name diff --git a/spec/libraries/powershell_module_provider_spec.rb b/spec/libraries/powershell_module_provider_spec.rb index bb5862a..0703807 100644 --- a/spec/libraries/powershell_module_provider_spec.rb +++ b/spec/libraries/powershell_module_provider_spec.rb @@ -72,41 +72,36 @@ describe 'download_extract_module:' do before do allow(@provider).to receive(:module_exists?).and_return false + allow(@provider).to receive(:unzip) + allow(@provider).to receive(:remove_download) end context 'when download_url and target are nil' do it 'downloads the package' do - cmd_str = "powershell.exe Invoke-WebRequest testmodule -OutFile C:/tmp/testmodule.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('C:\\tmp\\testmodule.zip'); $shell.Namespace('\\').copyhere($zip.items(), 0x14);write-host $shell" - expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(double('ps_cmd', run_command: nil)) - - expect(@provider.send(:download_extract_module)).to eq('C:/tmp/testmodule.zip') + expect(@provider).to receive(:download).with('testmodule', 'C:/tmp/testmodule.zip') + @provider.send(:download_extract_module) end end context 'when download_url is provided and target is nil' do it 'downloads the package' do - cmd_str = "powershell.exe Invoke-WebRequest https:/temp_download.com -OutFile C:/tmp/testmodule.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('C:\\tmp\\testmodule.zip'); $shell.Namespace('\\').copyhere($zip.items(), 0x14);write-host $shell" - expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(double('ps_cmd', run_command: nil)) - - expect(@provider.send(:download_extract_module, 'https:/temp_download.com')).to eq('C:/tmp/testmodule.zip') + expect(@provider).to receive(:download_extract_module).with('https://temp_download.com') + @provider.send(:download_extract_module, 'https://temp_download.com') end end context 'when download_url is nil and target is provided' do it 'downloads the package' do - cmd_str = "powershell.exe Invoke-WebRequest testmodule -OutFile tmp/target1.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('tmp\\target1.zip'); $shell.Namespace('\\').copyhere($zip.items(), 0x14);write-host $shell" - expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(double('ps_cmd', run_command: nil)) - - expect(@provider.send(:download_extract_module, nil, 'tmp/target1.zip')).to eq('tmp/target1.zip') + expect(@provider).to receive(:download).with('testmodule', 'C:/other_tmp/testmodule.zip') + @provider.send(:download_extract_module, nil, 'C:/other_tmp/testmodule.zip') end end context 'when download_url and target are provided' do it 'downloads the package' do - cmd_str = "powershell.exe Invoke-WebRequest https:/temp_download.com -OutFile tmp/target1.zip; $shell = new-object -com shell.application;$zip = $shell.NameSpace('tmp\\target1.zip'); $shell.Namespace('\\').copyhere($zip.items(), 0x14);write-host $shell" - expect(Mixlib::ShellOut).to receive(:new).with(cmd_str).and_return(double('ps_cmd', run_command: nil)) + expect(@provider).to receive(:download).with('https://temp_download.com', 'tmp/target1.zip') - expect(@provider.send(:download_extract_module, 'https:/temp_download.com', 'tmp/target1.zip')).to eq('tmp/target1.zip') + @provider.send(:download_extract_module, 'https://temp_download.com', 'tmp/target1.zip') end end end @@ -160,9 +155,7 @@ @new_resource.source source expect(Dir).to receive(:exist?).with(source).and_return(false) - expect(@provider).to receive(:download_extract_module).and_return(destination) - expect(File).to receive(:exist?).with(destination).and_return(true) - expect(FileUtils).to receive(:rm_f).with(destination) + expect(@provider).to receive(:download_extract_module) @provider.send(:install_module) end From ff1d46790034ec1110d6497e3ba34f5ee631ae47 Mon Sep 17 00:00:00 2001 From: Steven Murawski Date: Fri, 11 Dec 2015 12:50:26 -0600 Subject: [PATCH 13/14] fix a few tests on non-windows and pend the others until windows securables are testable crossplatform --- libraries/powershell_module_provider.rb | 4 ++-- spec/libraries/powershell_module_provider_spec.rb | 1 - spec/recipes/disable_lcm_spec.rb | 9 ++++++--- spec/recipes/enable_dsc_script_spec.rb | 2 +- spec/recipes/enable_lcm_spec.rb | 2 +- spec/spec_helper.rb | 4 ++++ 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/libraries/powershell_module_provider.rb b/libraries/powershell_module_provider.rb index e804867..e0d5c1f 100644 --- a/libraries/powershell_module_provider.rb +++ b/libraries/powershell_module_provider.rb @@ -99,8 +99,8 @@ def unzip(zip_file, target_directory) require 'zip' rescue LoadError raise( - 'Could not load the rubyzip gem, please make sure this gem is installed with the "chef_gem" resource ' \ - 'or include the powershell::default recipe before using powershell_module.' + 'Could not load the rubyzip gem, please make sure this gem is installed with the "chef_gem" resource ' \ + 'or include the powershell::default recipe before using powershell_module.' ) end diff --git a/spec/libraries/powershell_module_provider_spec.rb b/spec/libraries/powershell_module_provider_spec.rb index 0703807..c843537 100644 --- a/spec/libraries/powershell_module_provider_spec.rb +++ b/spec/libraries/powershell_module_provider_spec.rb @@ -151,7 +151,6 @@ context 'source is a url' do it 'downloads module from source and install' do source = 'https:/testmodule.com' - destination = 'C:/tmp/testmodule' @new_resource.source source expect(Dir).to receive(:exist?).with(source).and_return(false) diff --git a/spec/recipes/disable_lcm_spec.rb b/spec/recipes/disable_lcm_spec.rb index 37000d2..b6378e2 100644 --- a/spec/recipes/disable_lcm_spec.rb +++ b/spec/recipes/disable_lcm_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' require 'chefspec' + + describe 'powershell::disable_lcm' do let(:chef_run) do ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| @@ -35,14 +37,15 @@ $LCM.RefreshMode -eq "Disabled" EOH stub_command(guard_condition).and_return(false) - allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::powershell5').and_return(true) allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::dsc').and_return(true) end + - it 'disables LCM' do + it 'disables LCM', skip: not_windows? do expect(chef_run).to create_directory('Creating temporary directory to store LCM MOF files').with( - path: 'c:\\chef\\cache\\lcm_mof' + path: 'c:\\chef\\cache\\lcm_mof', + rights: [:read, 'Everyone'] ) expect(chef_run).to run_powershell_script('Disable LCM').with( code: @config_code diff --git a/spec/recipes/enable_dsc_script_spec.rb b/spec/recipes/enable_dsc_script_spec.rb index 823ae4a..48042e6 100644 --- a/spec/recipes/enable_dsc_script_spec.rb +++ b/spec/recipes/enable_dsc_script_spec.rb @@ -17,7 +17,7 @@ stub_command(guard_condition).and_return(false) end - it 'includes enable_lcm recipe' do + it 'includes enable_lcm recipe', skip: not_windows? do expect(chef_run).to include_recipe('powershell::enable_lcm') end end diff --git a/spec/recipes/enable_lcm_spec.rb b/spec/recipes/enable_lcm_spec.rb index cd4650e..f1ed8d7 100644 --- a/spec/recipes/enable_lcm_spec.rb +++ b/spec/recipes/enable_lcm_spec.rb @@ -42,7 +42,7 @@ allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::dsc').and_return(true) end - it 'enables LCM' do + it 'enables LCM', skip: not_windows? do expect(chef_run).to create_directory('Creating temporary directory to store LCM MOF files').with( path: 'c:\\chef\\cache\\lcm_mof' ) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e667e88..94ac410 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,7 @@ require 'chefspec' require 'chefspec/berkshelf' require 'helpers/matchers' + +def not_windows? + (RUBY_PLATFORM =~ /mswin|mingw|windows/).nil? +end From e73841e8ba685e32a2cb322bcc4882077ad81225 Mon Sep 17 00:00:00 2001 From: Steven Murawski Date: Fri, 11 Dec 2015 13:21:14 -0600 Subject: [PATCH 14/14] Fix style errors --- libraries/powershell_module_provider.rb | 14 ++++---------- spec/recipes/disable_lcm_spec.rb | 5 +---- spec/recipes/enable_dsc_script_spec.rb | 2 +- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/libraries/powershell_module_provider.rb b/libraries/powershell_module_provider.rb index e0d5c1f..b70b09d 100644 --- a/libraries/powershell_module_provider.rb +++ b/libraries/powershell_module_provider.rb @@ -82,7 +82,7 @@ def uninstall_module def download(download_url, target) uri = URI(download_url) - Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http| + Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| f = open(target, 'wb') http.request_get(uri.path) do |resp| resp.read_body do |segment| @@ -105,12 +105,10 @@ def unzip(zip_file, target_directory) end Zip::File.open(zip_file) do |zip| - zip.each do |entry| - FileUtils::mkdir_p(::File.join(target_directory, ::File.dirname(entry.name))) + FileUtils.mkdir_p(::File.join(target_directory, ::File.dirname(entry.name))) entry.extract(::File.join(target_directory, entry.name)) end - end end @@ -126,9 +124,7 @@ def download_extract_module(download_url = nil, target = nil) ps_module_path = sanitize! @new_resource.destination Chef::Log.debug("Powershell Module ps_module_path is #{ps_module_path}") - installed_module = module_exists?(ps_module_path, "*#{@new_resource.package_name}*") - if installed_module Chef::Log.info("Powershell Module #{@new_resource.package_name} already installed.") Chef::Log.info("Remove path at #{ps_module_path}\\#{installed_module} to reinstall.") @@ -140,10 +136,8 @@ def download_extract_module(download_url = nil, target = nil) end def remove_download(target) - if ::File.exist?(target) - Chef::Log.debug("Powershell Module '#{@powershell_module.package_name}' removing download #{downloaded_file}") - FileUtils.rm_f(downloaded_file) - end + Chef::Log.debug("Powershell Module '#{@powershell_module.package_name}' removing download #{downloaded_file}") + FileUtils.rm_f(downloaded_file) if ::File.exist?(target) end def module_path_name diff --git a/spec/recipes/disable_lcm_spec.rb b/spec/recipes/disable_lcm_spec.rb index b6378e2..e220680 100644 --- a/spec/recipes/disable_lcm_spec.rb +++ b/spec/recipes/disable_lcm_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' require 'chefspec' - - describe 'powershell::disable_lcm' do let(:chef_run) do ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| @@ -40,12 +38,11 @@ allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::powershell5').and_return(true) allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('powershell::dsc').and_return(true) end - it 'disables LCM', skip: not_windows? do expect(chef_run).to create_directory('Creating temporary directory to store LCM MOF files').with( path: 'c:\\chef\\cache\\lcm_mof', - rights: [:read, 'Everyone'] + rights: [permissions: :read, principals: 'Everyone'] ) expect(chef_run).to run_powershell_script('Disable LCM').with( code: @config_code diff --git a/spec/recipes/enable_dsc_script_spec.rb b/spec/recipes/enable_dsc_script_spec.rb index 48042e6..f155892 100644 --- a/spec/recipes/enable_dsc_script_spec.rb +++ b/spec/recipes/enable_dsc_script_spec.rb @@ -2,7 +2,7 @@ require 'chefspec' describe 'powershell::enable_dsc_script' do - let(:chef_run) do + let(:chef_run) do ChefSpec::SoloRunner.new(platform: 'windows', version: '2012') do |node| node.set['ms_dotnet']['v4']['version'] = '4.5' end.converge(described_recipe)