powershell resource: Add support other OSs (#2894)

This adds `powershell` resource support for non-Windows OSs via `pwsh`
and Base64 encoded commands.

Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com>
This commit is contained in:
Jerry Aldrich 2018-03-29 08:57:15 -07:00 committed by Jared Quick
parent 6665555a73
commit 2c4f041e9d
3 changed files with 34 additions and 21 deletions

View file

@ -17,9 +17,22 @@ module Inspec::Resources
"
def initialize(script)
# since WinRM 2.0 and the default use of powershell for local execution in
# train, we do not need to wrap the script here anymore
super(script)
# PowerShell is the default shell on Windows, use the `command` resource
return super(script) if inspec.os.windows?
unless inspec.command('pwsh').exist?
raise Inspec::Exceptions::ResourceSkipped, 'Can not find `pwsh` command'
end
# Prevent progress stream from leaking into stderr
command = "$ProgressPreference='SilentlyContinue';" + script
# Encode as Base64 to remove any quotes/escapes/etc issues
command = command.encode('UTF-16LE', 'UTF-8')
command = Base64.strict_encode64(command)
# Use the `command` resource to execute the command via `pwsh`
super("pwsh -encodedCommand '#{command}'")
end
# we cannot determine if a command exists, because that does not work for scripts

View file

@ -215,6 +215,7 @@ class MockLoader
'bash -c \'type "/test/path/pip"\'' => empty.call,
'bash -c \'type "Rscript"\'' => empty.call,
'bash -c \'type "perl"\'' => empty.call,
'type "pwsh"' => empty.call,
'type "netstat"' => empty.call,
'sh -c \'find /etc/apache2/ports.conf -type l -maxdepth 1\'' => empty.call,
'sh -c \'find /etc/httpd/conf.d/*.conf -type l -maxdepth 1\'' => empty.call,

View file

@ -5,28 +5,27 @@
require 'helper'
require 'inspec/resource'
describe 'Inspec::Resources::Powershell' do
describe 'Inspec::Resources::PowershellScript' do
let(:base64_command) {
# Encoded version of `$ProgressPreference='SilentlyContinue';Get-Help`
'JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQA9ACcAUwBpAGwA' \
'ZQBuAHQAbAB5AEMAbwBuAHQAaQBuAHUAZQAnADsARwBlAHQALQBIAGUAbABwAA=='
}
ps1_script = <<-EOH
# call help for get command
Get-Help Get-Command
EOH
it 'properly generates command' do
resource = MockLoader.new(:windows).load_resource('powershell', 'Get-Help')
_(resource.command).must_equal 'Get-Help'
it 'check if `powershell` for windows is properly generated ' do
resource = MockLoader.new(:windows).load_resource('powershell', ps1_script)
# string should be the same
_(resource.command.to_s).must_equal ps1_script
resource = MockLoader.new(:osx104).load_resource('powershell', 'Get-Help')
_(resource.command).must_equal("pwsh -encodedCommand '#{base64_command}'")
end
it 'check if legacy `script` for windows is properly generated ' do
resource = MockLoader.new(:windows).load_resource('script', ps1_script)
# string should be the same
_(resource.command.to_s).must_equal ps1_script
end
it 'properly generates command if deprecated `script` is used on Windows' do
Inspec::Resources::LegacyPowershellScript.any_instance.stubs(:deprecated)
resource = MockLoader.new(:windows).load_resource('script', 'Get-Help')
_(resource.command).must_equal 'Get-Help'
it 'will return an empty array when called on a non-supported OS with children' do
resource = MockLoader.new.load_resource('powershell', '...')
# string should be the same
_(resource.stdout).must_equal ''
resource = MockLoader.new(:osx104).load_resource('script', 'Get-Help')
_(resource.command).must_equal("pwsh -encodedCommand '#{base64_command}'")
end
end