mirror of
https://github.com/inspec/inspec
synced 2024-12-12 14:22:38 +00:00
d3b90a7c9f
* Add python check for pip resource When checking pip resources, we should skip resource if python is not installed or we will fail with an error when trying to parse the path. * Check pip command on windows On Windows, if pip has a newer version available, it adds an error message to stderr. Now checking if both stderr and stdout on windows have values. If so, assume pip package is installed. * Clean up powershell query command - Make it easier to read what the powershell command is doing - Make it easier to read what the cmd_successful method lokos for Signed-off-by: Paul Welch <pwelch@chef.io>
130 lines
3.4 KiB
Ruby
130 lines
3.4 KiB
Ruby
# encoding: utf-8
|
|
|
|
# Usage:
|
|
# describe pip('Jinja2') do
|
|
# it { should be_installed }
|
|
# end
|
|
#
|
|
|
|
module Inspec::Resources
|
|
class PipPackage < Inspec.resource(1)
|
|
name 'pip'
|
|
supports platform: 'unix'
|
|
supports platform: 'windows'
|
|
desc 'Use the pip InSpec audit resource to test packages that are installed using the pip installer.'
|
|
example "
|
|
describe pip('Jinja2') do
|
|
it { should be_installed }
|
|
end
|
|
|
|
describe pip('django', '/path/to/virtualenv/bin/pip') do
|
|
it { should be_installed }
|
|
its('version') { should eq('1.11.4')}
|
|
end
|
|
"
|
|
|
|
def initialize(package_name, pip_path = nil)
|
|
@package_name = package_name
|
|
@pip_cmd = pip_path || default_pip_path
|
|
|
|
return skip_resource 'pip not found' if @pip_cmd.nil?
|
|
end
|
|
|
|
def info
|
|
return @info if defined?(@info)
|
|
|
|
@info = {}
|
|
@info[:type] = 'pip'
|
|
return @info unless cmd_successful?
|
|
|
|
params = SimpleConfig.new(
|
|
cmd.stdout,
|
|
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
multiple_values: false,
|
|
).params
|
|
@info[:name] = params['Name']
|
|
@info[:version] = params['Version']
|
|
@info[:installed] = true
|
|
@info
|
|
end
|
|
|
|
def installed?
|
|
info[:installed] == true
|
|
end
|
|
|
|
def version
|
|
info[:version]
|
|
end
|
|
|
|
def to_s
|
|
"Pip Package #{@package_name}"
|
|
end
|
|
|
|
private
|
|
|
|
def cmd
|
|
@__cmd ||= inspec.command("#{@pip_cmd} show #{@package_name}")
|
|
end
|
|
|
|
def cmd_successful?
|
|
return true if cmd.exit_status == 0
|
|
|
|
if cmd.exit_status != 0
|
|
# If pip on windows is not the latest, it will create a stderr value along with stdout
|
|
# Example:
|
|
# stdout: "Name: Jinja2\r\nVersion: 2.10..."
|
|
# stderr: "You are using pip version 9.0.1, however version 9.0.3 is available..."
|
|
if inspec.os.windows? && !cmd.stdout.empty?
|
|
return true
|
|
end
|
|
end
|
|
|
|
false
|
|
end
|
|
|
|
# Paths of Python and Pip on windows
|
|
# {"Pip" => nil, "Python" => "/path/to/python"}
|
|
#
|
|
# @return [Hash] of windows_paths
|
|
def windows_paths
|
|
return @__windows_paths if @__windows_paths
|
|
cmd = inspec.command(
|
|
'New-Object -Type PSObject |
|
|
Add-Member -MemberType NoteProperty -Name Pip -Value (Invoke-Command -ScriptBlock {where.exe pip}) -PassThru |
|
|
Add-Member -MemberType NoteProperty -Name Python -Value (Invoke-Command -ScriptBlock {where.exe python}) -PassThru |
|
|
ConvertTo-Json',
|
|
)
|
|
|
|
@__windows_paths = JSON.parse(cmd.stdout)
|
|
end
|
|
|
|
# Default path of python pip installation
|
|
#
|
|
# @return [String] of python pip path
|
|
def default_pip_path
|
|
return 'pip' unless inspec.os.windows?
|
|
|
|
# If python is not found, return with skip_resource
|
|
return skip_resource 'python not found' if windows_paths['Python'].nil?
|
|
|
|
# Pip is not on the default path for Windows, therefore we do some logic
|
|
# to find the binary on Windows
|
|
begin
|
|
# use pip if it on system path
|
|
pipcmd = windows_paths['Pip']
|
|
# calculate path on windows
|
|
if defined?(windows_paths['Python']) && pipcmd.nil?
|
|
return nil if windows_paths['Pip'].nil?
|
|
pipdir = windows_paths['Python'].split('\\')
|
|
# remove python.exe
|
|
pipdir.pop
|
|
pipcmd = pipdir.push('Scripts').push('pip.exe').join('/')
|
|
end
|
|
rescue JSON::ParserError => _e
|
|
return nil
|
|
end
|
|
|
|
pipcmd
|
|
end
|
|
end
|
|
end
|