mirror of
https://github.com/inspec/inspec
synced 2024-11-23 13:13:22 +00:00
add *_service overrides, allowing for different control binaries
This commit is contained in:
parent
4192dedd14
commit
0e410df69d
2 changed files with 159 additions and 16 deletions
|
@ -34,10 +34,10 @@ class Service < Inspec.resource(1)
|
|||
@service_name = service_name
|
||||
@service_mgmt = nil
|
||||
@cache = nil
|
||||
select_package_manager
|
||||
select_service_ctl
|
||||
end
|
||||
|
||||
def select_package_manager # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
||||
def select_service_ctl # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
||||
family = inspec.os[:family]
|
||||
|
||||
case family
|
||||
|
@ -117,17 +117,22 @@ class Service < Inspec.resource(1)
|
|||
end
|
||||
|
||||
class ServiceManager
|
||||
attr_reader :inspec
|
||||
def initialize(inspec)
|
||||
attr_reader :inspec, :service_ctl
|
||||
def initialize(inspec, service_ctl = nil)
|
||||
@inspec = inspec
|
||||
@service_ctl = service_ctl
|
||||
end
|
||||
end
|
||||
|
||||
# @see: http://www.freedesktop.org/software/systemd/man/systemctl.html
|
||||
# @see: http://www.freedesktop.org/software/systemd/man/systemd-system.conf.html
|
||||
class Systemd < ServiceManager
|
||||
def initialize(inspec, service_ctl = 'systemctl')
|
||||
super
|
||||
end
|
||||
|
||||
def info(service_name)
|
||||
cmd = inspec.command("systemctl show --all #{service_name}")
|
||||
cmd = inspec.command("#{service_ctl} show --all #{service_name}")
|
||||
return nil if cmd.exit_status.to_i != 0
|
||||
|
||||
# parse data
|
||||
|
@ -206,9 +211,13 @@ end
|
|||
|
||||
# @see: http://upstart.ubuntu.com
|
||||
class Upstart < ServiceManager
|
||||
def initialize(service_name, service_ctl = 'initctl')
|
||||
super
|
||||
end
|
||||
|
||||
def info(service_name)
|
||||
# get the status of upstart service
|
||||
status = inspec.command("initctl status #{service_name}")
|
||||
status = inspec.command("#{service_ctl} status #{service_name}")
|
||||
|
||||
# fallback for systemv services, those are not handled via `initctl`
|
||||
return SysV.new(inspec).info(service_name) if status.exit_status.to_i != 0
|
||||
|
@ -235,7 +244,7 @@ class Upstart < ServiceManager
|
|||
# $ initctl show-config $job | grep -q "^ start on" && echo enabled || echo disabled
|
||||
# Ubuntu 10.04 show-config is not supported
|
||||
# @see http://manpages.ubuntu.com/manpages/maverick/man8/initctl.8.html
|
||||
config = inspec.command("initctl show-config #{service_name}")
|
||||
config = inspec.command("#{service_ctl} show-config #{service_name}")
|
||||
enabled = !config.stdout[/^\s*start on/].nil?
|
||||
|
||||
# implement fallback for Ubuntu 10.04
|
||||
|
@ -251,6 +260,10 @@ class Upstart < ServiceManager
|
|||
end
|
||||
|
||||
class SysV < ServiceManager
|
||||
def initialize(service_name, service_ctl = 'service')
|
||||
super
|
||||
end
|
||||
|
||||
def info(service_name)
|
||||
# check if service is installed
|
||||
# read all available services via ls /etc/init.d/
|
||||
|
@ -270,19 +283,21 @@ class SysV < ServiceManager
|
|||
enabled_services = enabled_services_cmd.stdout.split("\n").select { |line|
|
||||
/(^.*#{service_name}.*)/.match(line)
|
||||
}
|
||||
enabled_services.empty? ? enabled = false : enabled = true
|
||||
enabled = !enabled_services.empty?
|
||||
|
||||
# check if service is really running
|
||||
# service throws an exit code if the service is not installed or
|
||||
# not enabled
|
||||
|
||||
# FIXME(sr)
|
||||
# on debian service is located /usr/sbin/service, on centos it is located here /sbin/service
|
||||
service_cmd = 'service'
|
||||
service_cmd = '/usr/sbin/service' if inspec.os[:family] == 'debian'
|
||||
service_cmd = '/sbin/service' if inspec.os[:family] == 'centos'
|
||||
# service_cmd = 'service'
|
||||
# service_cmd = '/usr/sbin/service' if inspec.os[:family] == 'debian'
|
||||
# service_cmd = '/sbin/service' if inspec.os[:family] == 'centos'
|
||||
# NOTE(sr) It's all in PATH, isn't it?
|
||||
|
||||
cmd = inspec.command("#{service_cmd} #{service_name} status")
|
||||
cmd.exit_status == 0 ? (running = true) : (running = false)
|
||||
cmd = inspec.command("#{service_ctl} #{service_name} status")
|
||||
running = cmd.exit_status == 0
|
||||
{
|
||||
name: service_name,
|
||||
description: nil,
|
||||
|
@ -297,6 +312,10 @@ end
|
|||
# @see: https://www.freebsd.org/doc/en/articles/linux-users/startup.html
|
||||
# @see: https://www.freebsd.org/cgi/man.cgi?query=rc.conf&sektion=5
|
||||
class BSDInit < ServiceManager
|
||||
def initialize(service_name, service_ctl = 'service')
|
||||
super
|
||||
end
|
||||
|
||||
def info(service_name)
|
||||
# check if service is enabled
|
||||
# services are enabled in /etc/rc.conf and /etc/defaults/rc.conf
|
||||
|
@ -304,7 +323,7 @@ class BSDInit < ServiceManager
|
|||
# service SERVICE status returns the following result if not activated:
|
||||
# Cannot 'status' sshd. Set sshd_enable to YES in /etc/rc.conf or use 'onestatus' instead of 'status'.
|
||||
# gather all enabled services
|
||||
cmd = inspec.command('service -e')
|
||||
cmd = inspec.command("#{service_ctl} -e")
|
||||
return nil if cmd.exit_status != 0
|
||||
|
||||
# search for the service
|
||||
|
@ -314,7 +333,7 @@ class BSDInit < ServiceManager
|
|||
|
||||
# check if the service is running
|
||||
# if the service is not available or not running, we always get an error code
|
||||
cmd = inspec.command("service #{service_name} onestatus")
|
||||
cmd = inspec.command("#{service_ctl} #{service_name} onestatus")
|
||||
cmd.exit_status == 0 ? (running = true) : (running = false)
|
||||
|
||||
{
|
||||
|
@ -331,9 +350,13 @@ end
|
|||
# MacOS / Darwin
|
||||
# new launctl on macos 10.10
|
||||
class LaunchCtl < ServiceManager
|
||||
def initialize(service_name, service_ctl = 'launchctl')
|
||||
super
|
||||
end
|
||||
|
||||
def info(service_name)
|
||||
# get the status of upstart service
|
||||
cmd = inspec.command('launchctl list')
|
||||
cmd = inspec.command("#{service_ctl} list")
|
||||
return nil if cmd.exit_status != 0
|
||||
|
||||
# search for the service
|
||||
|
@ -442,3 +465,113 @@ class WindowsSrv < ServiceManager
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
class SystemdService < Service
|
||||
name 'systemd_service'
|
||||
desc 'Use the systemd_service InSpec audit resource to test if the named service (controlled by systemd) is installed, running and/or enabled.'
|
||||
example "
|
||||
# to override service mgmt auto-detection
|
||||
describe systemd_service('service_name') do
|
||||
it { should be_installed }
|
||||
it { should be_enabled }
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
# to set a non-standard systemctl path
|
||||
describe systemd_service('service_name', '/path/to/systemctl') do
|
||||
it { should be_running }
|
||||
end
|
||||
"
|
||||
|
||||
def select_service_ctl
|
||||
@service_mgmt = Systemd.new(inspec)
|
||||
end
|
||||
end
|
||||
|
||||
class UpstartService < Service
|
||||
name 'upstart_service'
|
||||
desc 'Use the upstart_service InSpec audit resource to test if the named service (controlled by upstart) is installed, running and/or enabled.'
|
||||
example "
|
||||
# to override service mgmt auto-detection
|
||||
describe upstart_service('service_name') do
|
||||
it { should be_installed }
|
||||
it { should be_enabled }
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
# to set a non-standard initctl path
|
||||
describe upstart_service('service_name', '/path/to/initctl') do
|
||||
it { should be_running }
|
||||
end
|
||||
"
|
||||
|
||||
def select_service_ctl
|
||||
@service_mgmt = Upstart.new(inspec)
|
||||
end
|
||||
end
|
||||
|
||||
class SysVService < Service
|
||||
name 'sysv_service'
|
||||
desc 'Use the sysv_service InSpec audit resource to test if the named service (controlled by SysV) is installed, running and/or enabled.'
|
||||
example "
|
||||
# to override service mgmt auto-detection
|
||||
describe sysv_service('service_name') do
|
||||
it { should be_installed }
|
||||
it { should be_enabled }
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
# to set a non-standard service path
|
||||
describe sysv_service('service_name', '/path/to/service') do
|
||||
it { should be_running }
|
||||
end
|
||||
"
|
||||
|
||||
def select_service_ctl
|
||||
@service_mgmt = SysV.new(inspec)
|
||||
end
|
||||
end
|
||||
|
||||
class BSDService < Service
|
||||
name 'bsd_service'
|
||||
desc 'Use the bsd_service InSpec audit resource to test if the named service (controlled by BSD init) is installed, running and/or enabled.'
|
||||
example "
|
||||
# to override service mgmt auto-detection
|
||||
describe bsd_service('service_name') do
|
||||
it { should be_installed }
|
||||
it { should be_enabled }
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
# to set a non-standard service path
|
||||
describe bsd_service('service_name', '/path/to/service') do
|
||||
it { should be_running }
|
||||
end
|
||||
"
|
||||
|
||||
def select_service_ctl
|
||||
@service_mgmt = BSDInit.new(inspec)
|
||||
end
|
||||
end
|
||||
|
||||
class LaunchdService < Service
|
||||
name 'launchd_service'
|
||||
desc 'Use the launchd_service InSpec audit resource to test if the named service (controlled by launchd) is installed, running and/or enabled.'
|
||||
example "
|
||||
# to override service mgmt auto-detection
|
||||
describe launchd_service('service_name') do
|
||||
it { should be_installed }
|
||||
it { should be_enabled }
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
# to set a non-standard launchctl path
|
||||
describe launchd_service('service_name', '/path/to/launchctl') do
|
||||
it { should be_running }
|
||||
end
|
||||
"
|
||||
|
||||
def select_service_ctl
|
||||
@service_mgmt = LaunchCtl.new(inspec)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,6 +37,16 @@ describe 'Inspec::Resources::Service' do
|
|||
_(resource.running?).must_equal true
|
||||
end
|
||||
|
||||
# ubuntu 15.04 with systemd_service
|
||||
it 'verify ubuntu package parsing with systemd_service' do
|
||||
resource = MockLoader.new(:ubuntu1504).load_resource('systemd_service', 'sshd')
|
||||
srv = { name: 'sshd.service', description: 'OpenSSH server daemon', installed: true, running: true, enabled: true, type: 'systemd' }
|
||||
_(resource.info).must_equal srv
|
||||
_(resource.installed?).must_equal true
|
||||
_(resource.enabled?).must_equal true
|
||||
_(resource.running?).must_equal true
|
||||
end
|
||||
|
||||
# centos 6 with systemv
|
||||
it 'verify centos 6 package parsing' do
|
||||
resource = MockLoader.new(:centos6).load_resource('service', 'sshd')
|
||||
|
|
Loading…
Reference in a new issue