mirror of
https://github.com/inspec/inspec
synced 2024-11-26 22:50:36 +00:00
Add rpm_dbpath
support to the package resource (#1960)
Signed-off-by: Jerry Aldrich III <jerry@chef.io>
This commit is contained in:
parent
a0ebc43132
commit
cc6f1e90ca
4 changed files with 95 additions and 9 deletions
|
@ -96,6 +96,12 @@ The following examples show how to use this InSpec audit resource.
|
||||||
it { should_not be_running }
|
it { should_not be_running }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
### Verify if some_package is installed according to my_rpmdb
|
||||||
|
|
||||||
|
describe package('some_package', rpm_dbpath: '/var/lib/my_rpmdb') do
|
||||||
|
it { should be_installed }
|
||||||
|
end
|
||||||
|
|
||||||
### Verify if Memcached is installed, enabled, and running
|
### Verify if Memcached is installed, enabled, and running
|
||||||
|
|
||||||
Memcached is an in-memory key-value store that helps improve the performance of database-driven websites and can be installed, maintained, and tested using the `memcached` cookbook (maintained by Chef). The following example is from the `memcached` cookbook and shows how to use a combination of the `package`, `service`, and `port` InSpec audit resources to test if Memcached is installed, enabled, and running:
|
Memcached is an in-memory key-value store that helps improve the performance of database-driven websites and can be installed, maintained, and tested using the `memcached` cookbook (maintained by Chef). The following example is from the `memcached` cookbook and shows how to use a combination of the `package`, `service`, and `port` InSpec audit resources to test if Memcached is installed, enabled, and running:
|
||||||
|
|
|
@ -19,7 +19,7 @@ module Inspec::Resources
|
||||||
end
|
end
|
||||||
"
|
"
|
||||||
|
|
||||||
def initialize(package_name = nil) # rubocop:disable Metrics/AbcSize
|
def initialize(package_name = nil, opts = {}) # rubocop:disable Metrics/AbcSize
|
||||||
@package_name = package_name
|
@package_name = package_name
|
||||||
@name = @package_name
|
@name = @package_name
|
||||||
@cache = nil
|
@cache = nil
|
||||||
|
@ -30,7 +30,7 @@ module Inspec::Resources
|
||||||
if os.debian?
|
if os.debian?
|
||||||
@pkgman = Deb.new(inspec)
|
@pkgman = Deb.new(inspec)
|
||||||
elsif os.redhat? || %w{suse amazon fedora}.include?(os[:family])
|
elsif os.redhat? || %w{suse amazon fedora}.include?(os[:family])
|
||||||
@pkgman = Rpm.new(inspec)
|
@pkgman = Rpm.new(inspec, opts)
|
||||||
elsif ['arch'].include?(os[:family])
|
elsif ['arch'].include?(os[:family])
|
||||||
@pkgman = Pacman.new(inspec)
|
@pkgman = Pacman.new(inspec)
|
||||||
elsif ['darwin'].include?(os[:family])
|
elsif ['darwin'].include?(os[:family])
|
||||||
|
@ -46,6 +46,8 @@ module Inspec::Resources
|
||||||
else
|
else
|
||||||
return skip_resource 'The `package` resource is not supported on your OS yet.'
|
return skip_resource 'The `package` resource is not supported on your OS yet.'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
evaluate_missing_requirements
|
||||||
end
|
end
|
||||||
|
|
||||||
# returns true if the package is installed
|
# returns true if the package is installed
|
||||||
|
@ -71,6 +73,14 @@ module Inspec::Resources
|
||||||
def to_s
|
def to_s
|
||||||
"System Package #{@package_name}"
|
"System Package #{@package_name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def evaluate_missing_requirements
|
||||||
|
missing_requirements_string = @pkgman.missing_requirements.uniq.join(', ')
|
||||||
|
return if missing_requirements_string.empty?
|
||||||
|
skip_resource "The following requirements are not met for this resource: #{missing_requirements_string}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class PkgManagement
|
class PkgManagement
|
||||||
|
@ -78,6 +88,12 @@ module Inspec::Resources
|
||||||
def initialize(inspec)
|
def initialize(inspec)
|
||||||
@inspec = inspec
|
@inspec = inspec
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def missing_requirements
|
||||||
|
# Each provider can provide an Array of missing requirements that will be
|
||||||
|
# combined into a `skip_resource` message
|
||||||
|
[]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Debian / Ubuntu
|
# Debian / Ubuntu
|
||||||
|
@ -104,8 +120,25 @@ module Inspec::Resources
|
||||||
|
|
||||||
# RHEL family
|
# RHEL family
|
||||||
class Rpm < PkgManagement
|
class Rpm < PkgManagement
|
||||||
|
def initialize(inspec, opts)
|
||||||
|
super(inspec)
|
||||||
|
|
||||||
|
@dbpath = opts.fetch(:rpm_dbpath, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
def missing_requirements
|
||||||
|
missing_requirements = []
|
||||||
|
|
||||||
|
unless @dbpath.nil? || inspec.directory(@dbpath).directory?
|
||||||
|
missing_requirements << "RPMDB #{@dbpath} does not exist"
|
||||||
|
end
|
||||||
|
|
||||||
|
missing_requirements
|
||||||
|
end
|
||||||
|
|
||||||
def info(package_name)
|
def info(package_name)
|
||||||
cmd = inspec.command("rpm -qia #{package_name}")
|
rpm_cmd = rpm_command(package_name)
|
||||||
|
cmd = inspec.command(rpm_cmd)
|
||||||
# CentOS does not return an error code if the package is not installed,
|
# CentOS does not return an error code if the package is not installed,
|
||||||
# therefore we need to check for emptyness
|
# therefore we need to check for emptyness
|
||||||
return nil if cmd.exit_status.to_i != 0 || cmd.stdout.chomp.empty?
|
return nil if cmd.exit_status.to_i != 0 || cmd.stdout.chomp.empty?
|
||||||
|
@ -133,6 +166,17 @@ module Inspec::Resources
|
||||||
type: 'rpm',
|
type: 'rpm',
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def rpm_command(package_name)
|
||||||
|
cmd = ''
|
||||||
|
cmd += 'rpm -qia'
|
||||||
|
cmd += " --dbpath #{@dbpath}" if @dbpath
|
||||||
|
cmd += ' ' + package_name
|
||||||
|
|
||||||
|
cmd
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# MacOS / Darwin implementation
|
# MacOS / Darwin implementation
|
||||||
|
|
|
@ -153,6 +153,8 @@ class MockLoader
|
||||||
# Test DH parameters, 2048 bit long safe prime, generator 2 for dh_params in PEM format
|
# Test DH parameters, 2048 bit long safe prime, generator 2 for dh_params in PEM format
|
||||||
'dh_params.dh_pem' => mockfile.call('dh_params.dh_pem'),
|
'dh_params.dh_pem' => mockfile.call('dh_params.dh_pem'),
|
||||||
'default.toml' => mockfile.call('default.toml'),
|
'default.toml' => mockfile.call('default.toml'),
|
||||||
|
'/var/lib/fake_rpmdb' => mockdir.call(true),
|
||||||
|
'/var/lib/rpmdb_does_not_exist' => mockdir.call(false),
|
||||||
}
|
}
|
||||||
|
|
||||||
# create all mock commands
|
# create all mock commands
|
||||||
|
@ -165,6 +167,8 @@ class MockLoader
|
||||||
mock.mock_command('', '', '', 0)
|
mock.mock_command('', '', '', 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd_exit_1 = mock.mock_command('', '', '', 1)
|
||||||
|
|
||||||
mock.commands = {
|
mock.commands = {
|
||||||
'ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command' => cmd.call('ps-axo'),
|
'ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command' => cmd.call('ps-axo'),
|
||||||
'ps axo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command' => cmd.call('ps-axoZ'),
|
'ps axo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command' => cmd.call('ps-axoZ'),
|
||||||
|
@ -181,6 +185,8 @@ class MockLoader
|
||||||
'yum -v repolist all' => cmd.call('yum-repolist-all'),
|
'yum -v repolist all' => cmd.call('yum-repolist-all'),
|
||||||
'dpkg -s curl' => cmd.call('dpkg-s-curl'),
|
'dpkg -s curl' => cmd.call('dpkg-s-curl'),
|
||||||
'rpm -qia curl' => cmd.call('rpm-qia-curl'),
|
'rpm -qia curl' => cmd.call('rpm-qia-curl'),
|
||||||
|
'rpm -qia --dbpath /var/lib/fake_rpmdb curl' => cmd.call('rpm-qia-curl'),
|
||||||
|
'rpm -qia --dbpath /var/lib/rpmdb_does_not_exist curl' => cmd_exit_1,
|
||||||
'pacman -Qi curl' => cmd.call('pacman-qi-curl'),
|
'pacman -Qi curl' => cmd.call('pacman-qi-curl'),
|
||||||
'brew info --json=v1 curl' => cmd.call('brew-info--json-v1-curl'),
|
'brew info --json=v1 curl' => cmd.call('brew-info--json-v1-curl'),
|
||||||
'gem list --local -a -q ^not-installed$' => cmd.call('gem-list-local-a-q-not-installed'),
|
'gem list --local -a -q ^not-installed$' => cmd.call('gem-list-local-a-q-not-installed'),
|
||||||
|
|
|
@ -34,12 +34,42 @@ describe 'Inspec::Resources::Package' do
|
||||||
end
|
end
|
||||||
|
|
||||||
# centos
|
# centos
|
||||||
it 'verify centos package parsing' do
|
describe 'Rpm' do # rubocop:disable BlockLength
|
||||||
resource = MockLoader.new(:centos7).load_resource('package', 'curl')
|
let(:pkg) do
|
||||||
pkg = { name: 'curl', installed: true, version: '7.29.0-19.el7', type: 'rpm' }
|
{
|
||||||
_(resource.installed?).must_equal true
|
name: 'curl',
|
||||||
_(resource.version).must_equal '7.29.0-19.el7'
|
installed: true,
|
||||||
_(resource.info).must_equal pkg
|
version: '7.29.0-19.el7',
|
||||||
|
type: 'rpm',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can parse RPM package info' do
|
||||||
|
resource = MockLoader.new(:centos7).load_resource('package', 'curl')
|
||||||
|
_(resource.installed?).must_equal true
|
||||||
|
_(resource.version).must_equal '7.29.0-19.el7'
|
||||||
|
_(resource.info).must_equal pkg
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can build an `rpm` command containing `--dbpath`' do
|
||||||
|
resource = MockLoader.new(:centos7).load_resource(
|
||||||
|
'package',
|
||||||
|
'curl',
|
||||||
|
rpm_dbpath: '/var/lib/fake_rpmdb',
|
||||||
|
)
|
||||||
|
_(resource.installed?).must_equal true
|
||||||
|
_(resource.version).must_equal '7.29.0-19.el7'
|
||||||
|
_(resource.info).must_equal pkg
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can add to `resource_skipped` when `--rpmdb` path does not exist' do
|
||||||
|
resource = MockLoader.new(:centos7).load_resource(
|
||||||
|
'package',
|
||||||
|
'curl',
|
||||||
|
rpm_dbpath: '/var/lib/rpmdb_does_not_exist',
|
||||||
|
)
|
||||||
|
_(resource.resource_skipped).wont_equal nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# hpux
|
# hpux
|
||||||
|
|
Loading…
Reference in a new issue