mirror of
https://github.com/inspec/inspec
synced 2024-11-23 13:13:22 +00:00
Merge pull request #269 from chef/chris-rock/shell-help
Feature: Add shell `help resource` command
This commit is contained in:
commit
3d0a1b81d8
50 changed files with 409 additions and 106 deletions
|
@ -7,9 +7,20 @@ module Inspec
|
|||
class Resource
|
||||
def self.name(name = nil)
|
||||
return if name.nil?
|
||||
@name = name
|
||||
Inspec::Plugins::Resource.__register(name, self)
|
||||
end
|
||||
|
||||
def self.desc(description = nil)
|
||||
return if description.nil?
|
||||
Inspec::Resource.registry[@name].desc(description)
|
||||
end
|
||||
|
||||
def self.example(example = nil)
|
||||
return if example.nil?
|
||||
Inspec::Resource.registry[@name].example(example)
|
||||
end
|
||||
|
||||
def self.__register(name, obj)
|
||||
# rubocop:disable Lint/NestedMethodDefinition
|
||||
cl = Class.new(obj) do
|
||||
|
@ -23,6 +34,16 @@ module Inspec
|
|||
super(*args)
|
||||
end
|
||||
|
||||
def self.desc(description = nil)
|
||||
return @description if description.nil?
|
||||
@description = description
|
||||
end
|
||||
|
||||
def self.example(example = nil)
|
||||
return @example if example.nil?
|
||||
@example = example
|
||||
end
|
||||
|
||||
def inspec
|
||||
@__backend_runner__
|
||||
end
|
||||
|
|
|
@ -24,8 +24,8 @@ module Inspec
|
|||
that = self
|
||||
|
||||
# Add the help command
|
||||
Pry::Commands.block_command 'usage', 'Show examples' do
|
||||
that.usage
|
||||
Pry::Commands.block_command 'help', 'Show examples' do |resource|
|
||||
that.help(resource)
|
||||
end
|
||||
|
||||
# Add a help menu as the default intro
|
||||
|
@ -38,15 +38,30 @@ module Inspec
|
|||
"\033[1m#{x}\033[0m"
|
||||
end
|
||||
|
||||
def print_example(example)
|
||||
# determine min whitespace that can be removed
|
||||
min = nil
|
||||
example.lines.each do |line|
|
||||
if line.strip.length > 0 # ignore empty lines
|
||||
line_whitespace = line.length - line.lstrip.length
|
||||
min = line_whitespace if min.nil? || line_whitespace < min
|
||||
end
|
||||
end
|
||||
# remove whitespace from each line
|
||||
example.gsub(/\n\s{#{min}}/, "\n")
|
||||
end
|
||||
|
||||
def intro
|
||||
puts 'Welcome to the interactive Inspec Shell'
|
||||
puts "To find out how to use it, type: #{mark 'usage'}"
|
||||
puts 'Welcome to the interactive InSpec Shell'
|
||||
puts "To find out how to use it, type: #{mark 'help'}"
|
||||
puts
|
||||
end
|
||||
|
||||
def usage
|
||||
ctx = @runner.backend
|
||||
puts <<EOF
|
||||
def help(resource = nil)
|
||||
if resource.nil?
|
||||
|
||||
ctx = @runner.backend
|
||||
puts <<EOF
|
||||
|
||||
Welcome to the interactive Inspec Shell.
|
||||
|
||||
|
@ -56,12 +71,45 @@ For example:
|
|||
command('uname -a').stdout
|
||||
file('/proc/cpuinfo').content
|
||||
|
||||
To show all available resources:
|
||||
|
||||
help resources
|
||||
|
||||
You are currently running on:
|
||||
|
||||
OS family: #{mark ctx.os[:family] || 'unknown'}
|
||||
OS release: #{mark ctx.os[:release] || 'unknown'}
|
||||
|
||||
EOF
|
||||
elsif resource == 'resources'
|
||||
resources
|
||||
else
|
||||
|
||||
if !Inspec::Resource.registry[resource].nil?
|
||||
puts <<EOF
|
||||
#{mark 'Name:'} #{resource}
|
||||
|
||||
#{mark 'Description:'}
|
||||
|
||||
#{Inspec::Resource.registry[resource].desc}
|
||||
|
||||
#{mark 'Example:'}
|
||||
#{print_example(Inspec::Resource.registry[resource].example)}
|
||||
|
||||
#{mark 'Web Reference:'}
|
||||
|
||||
https://github.com/chef/inspec/blob/master/docs/resources.rst##{resource}
|
||||
|
||||
EOF
|
||||
else
|
||||
puts 'Only the following resources are available:'
|
||||
resources
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def resources
|
||||
puts Inspec::Resource.registry.keys.join(' ')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,12 @@ require 'utils/find_files'
|
|||
|
||||
class ApacheConf < Inspec.resource(1)
|
||||
name 'apache_conf'
|
||||
desc 'Use the apache_conf InSpec audit resource to test the configuration settings for Apache. This file is typically located under /etc/apache2 on the Debian and Ubuntu platforms and under /etc/httpd on the Fedora, CentOS, Red Hat Enterprise Linux, and Arch Linux platforms. The configuration settings may vary significantly from platform to platform.'
|
||||
example "
|
||||
describe apache_conf do
|
||||
its('setting_name') { should eq 'value' }
|
||||
end
|
||||
"
|
||||
|
||||
include FindFiles
|
||||
|
||||
|
|
|
@ -30,6 +30,13 @@ require 'uri'
|
|||
|
||||
class AptRepository < Inspec.resource(1)
|
||||
name 'apt'
|
||||
desc 'Use the apt InSpec audit resource to verify Apt repositories on the Debian and Ubuntu platforms, and also PPA repositories on the Ubuntu platform.'
|
||||
example "
|
||||
describe apt('nginx/stable') do
|
||||
it { should exist }
|
||||
it { should be_enabled }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(ppa_name)
|
||||
@deb_url = nil
|
||||
|
|
|
@ -23,15 +23,15 @@
|
|||
# - "Failure"
|
||||
#
|
||||
# Further information is available at: https://msdn.microsoft.com/en-us/library/dd973859.aspx
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# describe audit_policy do
|
||||
# its('Other Account Logon Events') { should_not eq 'No Auditing' }
|
||||
# end
|
||||
|
||||
class AuditPolicy < Inspec.resource(1)
|
||||
name 'audit_policy'
|
||||
desc 'Use the audit_policy InSpec audit resource to test auditing policies on the Microsoft Windows platform. An auditing policy is a category of security-related events to be audited. Auditing is disabled by default and may be enabled for categories like account management, logon events, policy changes, process tracking, privilege use, system events, or object access. For each auditing category property that is enabled, the auditing level may be set to No Auditing, Not Specified, Success, Success and Failure, or Failure.'
|
||||
example "
|
||||
describe audit_policy do
|
||||
its('parameter') { should eq 'value' }
|
||||
end
|
||||
"
|
||||
|
||||
def method_missing(method)
|
||||
key = method.to_s
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
|
||||
require 'utils/simpleconfig'
|
||||
|
||||
# Usage:
|
||||
# describe audit_daemon_conf do
|
||||
# its("space_left_action") { should eq "email" }
|
||||
# its("action_mail_acct") { should eq "root" }
|
||||
# its("admin_space_left_action") { should eq "halt" }
|
||||
# end
|
||||
|
||||
class AuditDaemonConf < Inspec.resource(1)
|
||||
name 'auditd_conf'
|
||||
desc "Use the auditd_conf InSpec audit resource to test the configuration settings for the audit daemon. This file is typically located under /etc/audit/auditd.conf' on UNIX and Linux platforms."
|
||||
example "
|
||||
describe auditd_conf do
|
||||
its('space_left_action') { should eq 'email' }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(path = nil)
|
||||
@conf_path = path || '/etc/audit/auditd.conf'
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
# author: Dominik Richter
|
||||
# license: All rights reserved
|
||||
|
||||
# Usage:
|
||||
# describe audit_daemon_rules do
|
||||
# its("LIST_RULES") {should contain_match(/^exit,always arch=.* key=time-change syscall=adjtimex,settimeofday/) }
|
||||
# its("LIST_RULES") {should contain_match(/^exit,always arch=.* key=time-change syscall=stime,settimeofday,adjtimex/) }
|
||||
# its("LIST_RULES") {should contain_match(/^exit,always arch=.* key=time-change syscall=clock_settime/)}
|
||||
# its("LIST_RULES") {should contain_match(/^exit,always watch=\/etc\/localtime perm=wa key=time-change/)}
|
||||
# end
|
||||
|
||||
class AuditDaemonRules < Inspec.resource(1)
|
||||
name 'auditd_rules'
|
||||
desc 'Use the auditd_rules InSpec audit resource to test the rules for logging that exist on the system. The audit.rules file is typically located under /etc/audit/ and contains the list of rules that define what is captured in log files.'
|
||||
example "
|
||||
describe auditd_rules do
|
||||
its('LIST_RULES') {should contain_match(/^exit,always arch=.* key=time-change syscall=adjtimex,settimeofday/) }
|
||||
its('LIST_RULES') {should contain_match(/^exit,always arch=.* key=time-change syscall=stime,settimeofday,adjtimex/) }
|
||||
its('LIST_RULES') {should contain_match(/^exit,always arch=.* key=time-change syscall=clock_settime/)}
|
||||
its('LIST_RULES') {should contain_match(/^exit,always watch=\/etc\/localtime perm=wa key=time-change/)}
|
||||
end
|
||||
"
|
||||
|
||||
def initialize
|
||||
@content = inspec.command('/sbin/auditctl -l').stdout.chomp
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
|
||||
require 'resources/file'
|
||||
|
||||
# Usage:
|
||||
# describe bond('bond0') do
|
||||
# it { should exist }
|
||||
# it { should have_interface 'eth0' }
|
||||
# end
|
||||
|
||||
module Inspec::Resources
|
||||
class Bond < File
|
||||
name 'bond'
|
||||
desc 'Use the bond InSpec audit resource to test a logical, bonded network interface (i.e. "two or more network interfaces aggregated into a single, logical network interface"). On Linux platforms, any value in the /proc/net/bonding directory may be tested.'
|
||||
example "
|
||||
describe bond('bond0') do
|
||||
it { should exist }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(bond)
|
||||
@bond = bond
|
||||
|
|
|
@ -10,6 +10,13 @@
|
|||
|
||||
class Bridge < Inspec.resource(1)
|
||||
name 'bridge'
|
||||
desc 'Use the bridge InSpec audit resource to test basic network bridge properties, such as name, if an interface is defined, and the associations for any defined interface.'
|
||||
example "
|
||||
describe bridge 'br0' do
|
||||
it { should exist }
|
||||
it { should have_interface 'eth0' }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(bridge_name)
|
||||
@bridge_name = bridge_name
|
||||
|
|
|
@ -4,16 +4,18 @@
|
|||
# author: Christoph Hartmann
|
||||
# license: All rights reserved
|
||||
|
||||
# Usage:
|
||||
# describe command('ls -al /') do
|
||||
# it { should exist }
|
||||
# its(:stdout) { should match /bin/ }
|
||||
# its(:stderr) { should match /No such file or directory/ }
|
||||
# its(:exit_status) { should eq 0 }
|
||||
# end
|
||||
|
||||
class Cmd < Inspec.resource(1)
|
||||
name 'command'
|
||||
desc 'Use the command InSpec audit resource to test an arbitrary command that is run on the system.'
|
||||
example "
|
||||
describe command('ls -al /') do
|
||||
it { should exist }
|
||||
its(:stdout) { should match /bin/ }
|
||||
its('stderr') { should eq '' }
|
||||
its(:exit_status) { should eq 0 }
|
||||
end
|
||||
"
|
||||
|
||||
attr_reader :command
|
||||
|
||||
def initialize(cmd)
|
||||
|
|
|
@ -3,15 +3,16 @@
|
|||
# author: Dominik Richter
|
||||
|
||||
# Parses a csv document
|
||||
# Usage:
|
||||
# describe csv('example.csv') do
|
||||
# its('name') { should eq(['John', 'Alice']) }
|
||||
# end
|
||||
#
|
||||
# This implementation was inspired by a blog post
|
||||
# @see http://technicalpickles.com/posts/parsing-csv-with-ruby
|
||||
class CsvConfig < JsonConfig
|
||||
name 'csv'
|
||||
desc 'Use the csv InSpec audit resource to test configuration data in a CSV file.'
|
||||
example "
|
||||
describe csv('example.csv') do
|
||||
its('name') { should eq(['John', 'Alice']) }
|
||||
end
|
||||
"
|
||||
|
||||
# override file load and parse hash from csv
|
||||
def parse(content)
|
||||
|
|
|
@ -7,6 +7,12 @@ require 'resources/file'
|
|||
module Inspec::Resources
|
||||
class Directory < File
|
||||
name 'directory'
|
||||
desc 'Use the directory InSpec audit resource to test if the file type is a directory. This is equivalent to using the file InSpec audit resource and the be_directory matcher, but provides a simpler and more direct way to test directories. All of the matchers available to file may be used with directory.'
|
||||
example "
|
||||
describe directory('path') do
|
||||
it { should be_directory }
|
||||
end
|
||||
"
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
|
|
@ -29,6 +29,14 @@ class EtcGroup < Inspec.resource(1)
|
|||
include ContentParser
|
||||
|
||||
name 'etc_group'
|
||||
desc 'Use the etc_group InSpec audit resource to test groups that are defined on Linux and UNIX platforms. The /etc/group file stores details about each group---group name, password, group identifier, along with a comma-separate list of users that belong to the group.'
|
||||
example "
|
||||
describe etc_group do
|
||||
its('gids') { should_not contain_duplicates }
|
||||
its('groups') { should include 'my_user' }
|
||||
its('users') { should include 'my_user' }
|
||||
end
|
||||
"
|
||||
|
||||
attr_accessor :gid, :entries
|
||||
def initialize(path = nil)
|
||||
|
|
|
@ -7,6 +7,17 @@
|
|||
module Inspec::Resources
|
||||
class File < Inspec.resource(1)
|
||||
name 'file'
|
||||
desc 'Use the file InSpec audit resource to test all system file types, including files, directories, symbolic links, named pipes, sockets, character devices, block devices, and doors.'
|
||||
example "
|
||||
describe file('path') do
|
||||
it { should exist }
|
||||
it { should be_file }
|
||||
it { should be_readable }
|
||||
it { should be_writable }
|
||||
it { should be_owned_by 'root' }
|
||||
its('mode') { should eq 0644 }
|
||||
end
|
||||
"
|
||||
|
||||
attr_reader :path
|
||||
def initialize(path)
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
# author: Christoph Hartmann
|
||||
# author: Dominik Richter
|
||||
|
||||
# Usage:
|
||||
# describe gem('rubocop') do
|
||||
# it { should be_installed }
|
||||
# end
|
||||
class GemPackage < Inspec.resource(1)
|
||||
name 'gem'
|
||||
desc 'Use the gem InSpec audit resource to test if a global gem package is installed.'
|
||||
example "
|
||||
describe gem('rubocop') do
|
||||
it { should be_installed }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(package_name)
|
||||
@package_name = package_name
|
||||
|
|
|
@ -15,6 +15,13 @@
|
|||
|
||||
class Group < Inspec.resource(1)
|
||||
name 'group'
|
||||
desc 'Use the group InSpec audit resource to test groups on the system.'
|
||||
example "
|
||||
describe group('root') do
|
||||
it { should exist }
|
||||
its('gid') { should eq 0 }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(groupname, domain = nil)
|
||||
@group = groupname.downcase
|
||||
|
|
|
@ -26,6 +26,12 @@
|
|||
|
||||
class Host < Inspec.resource(1)
|
||||
name 'host'
|
||||
desc 'Use the host InSpec audit resource to test the name used to refer to a specific host and its availability, including the Internet protocols and ports over which that host name should be available.'
|
||||
example "
|
||||
describe host('example.com') do
|
||||
it { should be_reachable }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(hostname, params = {})
|
||||
@hostname = hostname
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
|
||||
require 'utils/simpleconfig'
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# describe inetd_conf do
|
||||
# its('shell') { should eq nil }
|
||||
# its('login') { should eq nil }
|
||||
# its('exec') { should eq nil }
|
||||
# end
|
||||
|
||||
class InetdConf < Inspec.resource(1)
|
||||
name 'inetd_conf'
|
||||
desc 'Use the inetd_conf InSpec audit resource to test if a service is enabled in the inetd.conf file on Linux and UNIX platforms. inetd---the Internet service daemon---listens on dedicated ports, and then loads the appropriate program based on a request. The inetd.conf file is typically located at /etc/inetd.conf and contains a list of Internet services associated to the ports on which that service will listen. Only enabled services may handle a request; only services that are required by the system should be enabled.'
|
||||
example "
|
||||
describe inetd_conf do
|
||||
its('shell') { should eq nil }
|
||||
its('login') { should eq nil }
|
||||
its('exec') { should eq nil }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(path = nil)
|
||||
@conf_path = path || '/etc/inetd.conf'
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
require 'utils/simpleconfig'
|
||||
|
||||
# Parses a ini file
|
||||
# Usage:
|
||||
# descibe ini do
|
||||
# its("auth_protocol") { should eq "https" }
|
||||
# end
|
||||
class IniConfig < JsonConfig
|
||||
name 'ini'
|
||||
|
||||
desc 'Use the ini InSpec audit resource to test data in a INI file.'
|
||||
example "
|
||||
descibe ini do
|
||||
its('auth_protocol') { should eq 'https' }
|
||||
end
|
||||
"
|
||||
# override file load and parse hash with simple config
|
||||
def parse(content)
|
||||
SimpleConfig.new(content).params
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
# author: Christoph Hartmann
|
||||
# author: Dominik Richter
|
||||
|
||||
# Usage:
|
||||
# describe interface('eth0') do
|
||||
# it { should exist }
|
||||
# it { should be_up }
|
||||
# its(:speed) { should eq 1000 }
|
||||
# end
|
||||
|
||||
require 'utils/convert'
|
||||
|
||||
class NetworkInterface < Inspec.resource(1)
|
||||
name 'interface'
|
||||
|
||||
desc 'Use the interface InSpec audit resource to test basic network adapter properties, such as name, status, state, address, and link speed (in MB/sec).'
|
||||
example "
|
||||
describe interface('eth0') do
|
||||
it { should exist }
|
||||
it { should be_up }
|
||||
its(:speed) { should eq 1000 }
|
||||
end
|
||||
"
|
||||
def initialize(iface)
|
||||
@iface = iface
|
||||
|
||||
|
|
|
@ -23,6 +23,12 @@
|
|||
# @see https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html
|
||||
class IpTables < Inspec.resource(1)
|
||||
name 'iptables'
|
||||
desc 'Use the iptables InSpec audit resource to test rules that are defined in iptables, which maintains tables of IP packet filtering rules. There may be more than one table. Each table contains one (or more) chains (both built-in and custom). A chain is a list of rules that match packets. When the rule matches, the rule defines what target to assign to the packet.'
|
||||
example "
|
||||
describe iptables do
|
||||
it { should have_rule('-P INPUT ACCEPT') }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(params = {})
|
||||
@table = params[:table] || nil
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
# author: Christoph Hartmann
|
||||
# author: Dominik Richter
|
||||
|
||||
# Parses a json document
|
||||
# Usage:
|
||||
# describe json('policyfile.lock.json') do
|
||||
# its('cookbook_locks.omnibus.version') { should eq('2.2.0') }
|
||||
# end
|
||||
class JsonConfig < Inspec.resource(1)
|
||||
name 'json'
|
||||
desc 'Use the json InSpec audit resource to test data in a JSON file.'
|
||||
example "
|
||||
describe json('policyfile.lock.json') do
|
||||
its('cookbook_locks.omnibus.version') { should eq('2.2.0') }
|
||||
end
|
||||
"
|
||||
|
||||
# make params readable
|
||||
attr_reader :params
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
# author: Dominik Richter
|
||||
# license: All rights reserved
|
||||
|
||||
# Verifies if a kernel module is loaded
|
||||
# Usage:
|
||||
# describe kernel_module('bridge') do
|
||||
# it { should be_loaded }
|
||||
# end
|
||||
class KernelModule < Inspec.resource(1)
|
||||
name 'kernel_module'
|
||||
desc 'Use the kernel_module InSpec audit resource to test kernel modules on Linux platforms. These parameters are located under /lib/modules. Any submodule may be tested using this resource.'
|
||||
example "
|
||||
describe kernel_module('bridge') do
|
||||
it { should be_loaded }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(modulename = nil)
|
||||
@module = modulename
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
# author: Christoph Hartmann
|
||||
# license: All rights reserved
|
||||
|
||||
# Verifies if a kernel parameter is set
|
||||
# describe kernel_parameter('net.ipv4.conf.all.forwarding') do
|
||||
# its(:value) { should eq 0 }
|
||||
# end
|
||||
class KernelParameter < Inspec.resource(1)
|
||||
name 'kernel_parameter'
|
||||
desc 'Use the kernel_parameter InSpec audit resource to test kernel parameters on Linux platforms.'
|
||||
example "
|
||||
describe kernel_parameter('net.ipv4.conf.all.forwarding') do
|
||||
its(:value) { should eq 0 }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(parameter = nil)
|
||||
@parameter = parameter
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
require 'utils/simpleconfig'
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# describe limits_conf do
|
||||
# its('*') { should include ['hard','core','0'] }
|
||||
# end
|
||||
|
||||
class LimitsConf < Inspec.resource(1)
|
||||
name 'limits_conf'
|
||||
desc 'Use the limits_conf InSpec audit resource to test configuration settings in the /etc/security/limits.conf file. The limits.conf defines limits for processes (by user and/or group names) and helps ensure that the system on which those processes are running remains stable. Each process may be assigned a hard or soft limit.'
|
||||
example "
|
||||
describe limits_conf do
|
||||
its('*') { should include ['hard','core','0'] }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(path = nil)
|
||||
@conf_path = path || '/etc/security/limits.conf'
|
||||
|
|
|
@ -20,6 +20,12 @@ require 'utils/simpleconfig'
|
|||
|
||||
class LoginDef < Inspec.resource(1)
|
||||
name 'login_defs'
|
||||
desc 'Use the login_defs InSpec audit resource to test configuration settings in the /etc/login.defs file. The logins.defs file defines site-specific configuration for the shadow password suite on Linux and UNIX platforms, such as password expiration ranges, minimum/maximum values for automatic selection of user and group identifiers, or the method with which passwords are encrypted.'
|
||||
example "
|
||||
describe login_defs do
|
||||
its('ENCRYPT_METHOD') { should eq 'SHA512' }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(path = nil)
|
||||
@conf_path = path || '/etc/login.defs'
|
||||
|
|
|
@ -28,6 +28,12 @@ end
|
|||
|
||||
class MysqlConf < Inspec.resource(1)
|
||||
name 'mysql_conf'
|
||||
desc 'Use the mysql_conf InSpec audit resource to test the contents of the configuration file for MySQL, typically located at /etc/mysql/my.cnf or /etc/my.cnf.'
|
||||
example "
|
||||
describe mysql_conf('path') do
|
||||
its('setting') { should eq 'value' }
|
||||
end
|
||||
"
|
||||
|
||||
include FindFiles
|
||||
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
|
||||
class MysqlSession < Inspec.resource(1)
|
||||
name 'mysql_session'
|
||||
desc 'Use the mysql_session InSpec audit resource to test SQL commands run against a MySQL database.'
|
||||
example "
|
||||
sql = mysql_session('my_user','password')
|
||||
describe sql.query('show databases like \'test\';') do
|
||||
its(:stdout) { should_not match(/test/) }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(user = nil, pass = nil)
|
||||
@user = user
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
# author: Christoph Hartmann
|
||||
# author: Dominik Richter
|
||||
|
||||
# Usage:
|
||||
# describe npm('bower') do
|
||||
# it { should be_installed }
|
||||
# end
|
||||
class NpmPackage < Inspec.resource(1)
|
||||
name 'npm'
|
||||
desc 'Use the npm InSpec audit resource to test if a global npm package is installed. npm is the the package manager for Nodejs packages, such as bower and StatsD.'
|
||||
example "
|
||||
describe npm('bower') do
|
||||
it { should be_installed }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(package_name)
|
||||
@package_name = package_name
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
|
||||
require 'utils/simpleconfig'
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# describe ntp_conf do
|
||||
# its('server') { should_not eq nil }
|
||||
# its('restrict') { should include '-4 default kod notrap nomodify nopeer noquery'}
|
||||
# end
|
||||
|
||||
class NtpConf < Inspec.resource(1)
|
||||
name 'ntp_conf'
|
||||
desc 'Use the ntp_conf InSpec audit resource to test the synchronization settings defined in the ntp.conf file. This file is typically located at /etc/ntp.conf.'
|
||||
example "
|
||||
describe ntp_conf do
|
||||
its('server') { should_not eq nil }
|
||||
its('restrict') { should include '-4 default kod notrap nomodify nopeer noquery'}
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(path = nil)
|
||||
@conf_path = path || '/etc/ntp.conf'
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
# end
|
||||
class OneGetPackage < Inspec.resource(1)
|
||||
name 'oneget'
|
||||
desc 'Use the oneget InSpec audit resource to test if the named package and/or package version is installed on the system. This resource uses OneGet, which is part of the Windows Management Framework 5.0 and Windows 10. This resource uses the Get-Package cmdlet to return all of the package names in the OneGet repository.'
|
||||
example "
|
||||
describe oneget('zoomit') do
|
||||
it { should be_installed }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(package_name)
|
||||
@package_name = package_name
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
|
||||
class OS < Inspec.resource(1)
|
||||
name 'os'
|
||||
desc 'Use the os InSpec audit resource to test the platform on which the system is running.'
|
||||
example "
|
||||
describe os[:family] do
|
||||
it { should eq 'redhat' }
|
||||
end
|
||||
"
|
||||
|
||||
# reuse helper methods from backend
|
||||
%w{redhat? debian? suse? bsd? solaris? linux? unix? windows?}.each do |os_family|
|
||||
|
|
|
@ -15,6 +15,12 @@ require 'utils/simpleconfig'
|
|||
|
||||
class OsEnv < Inspec.resource(1)
|
||||
name 'os_env'
|
||||
desc 'Use the os_env InSpec audit resource to test the environment variables for the platform on which the system is running.'
|
||||
example "
|
||||
describe os_env('VARIABLE') do
|
||||
its('matcher') { should eq 1 }
|
||||
end
|
||||
"
|
||||
|
||||
attr_reader :content
|
||||
def initialize(env = nil)
|
||||
|
|
|
@ -10,6 +10,13 @@
|
|||
# end
|
||||
class Package < Inspec.resource(1)
|
||||
name 'package'
|
||||
desc 'Use the package InSpec audit resource to test if the named package and/or package version is installed on the system.'
|
||||
example "
|
||||
describe package('nginx') do
|
||||
it { should be_installed }
|
||||
its('version') { should eq 1.9.5 }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(package_name = nil)
|
||||
@package_name = package_name
|
||||
|
|
|
@ -15,6 +15,14 @@
|
|||
|
||||
class PConfig < Inspec.resource(1)
|
||||
name 'parse_config'
|
||||
desc 'Use the parse_config InSpec audit resource to test arbitrary configuration files.'
|
||||
example "
|
||||
output = command('some-command').stdout
|
||||
|
||||
describe parse_config(output, { data_config_option: value } ) do
|
||||
its('setting') { should eq 1 }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(content = nil, useropts = nil)
|
||||
@opts = {}
|
||||
|
@ -63,6 +71,12 @@ end
|
|||
|
||||
class PConfigFile < PConfig
|
||||
name 'parse_config_file'
|
||||
desc 'Use the parse_config_file InSpec audit resource to test arbitrary configuration files. It works identiacal to parse_config. Instead of using a command output, this resource works with files.'
|
||||
example "
|
||||
describe parse_config_file('/path/to/file') do
|
||||
its('setting') { should eq 1 }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(path, opts = nil)
|
||||
super(nil, opts)
|
||||
|
|
|
@ -29,6 +29,13 @@ require 'utils/parser'
|
|||
|
||||
class Passwd < Inspec.resource(1)
|
||||
name 'passwd'
|
||||
desc 'Use the passwd InSpec audit resource to test the contents of /etc/passwd, which contains the following information for users that may log into the system and/or as users that own running processes.'
|
||||
example "
|
||||
describe passwd.uid(0) do
|
||||
its('username') { should eq 'root' }
|
||||
its('count') { should eq 1 }
|
||||
end
|
||||
"
|
||||
|
||||
include ContentParser
|
||||
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
#
|
||||
class PipPackage < Inspec.resource(1)
|
||||
name 'pip'
|
||||
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
|
||||
"
|
||||
|
||||
def initialize(package_name)
|
||||
@package_name = package_name
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
# TODO: improve handling of same port on multiple interfaces
|
||||
class Port < Inspec.resource(1)
|
||||
name 'port'
|
||||
desc "Use the port InSpec audit resource to test basic port properties, such as port, process, if it's listening."
|
||||
example "
|
||||
describe port(80) do
|
||||
it { should be_listening }
|
||||
its('protocol') {should eq 'tcp'}
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(port)
|
||||
@port = port
|
||||
|
|
|
@ -10,6 +10,12 @@ require 'resources/postgres'
|
|||
|
||||
class PostgresConf < Inspec.resource(1)
|
||||
name 'postgres_conf'
|
||||
desc 'Use the postgres_conf InSpec audit resource to test the contents of the configuration file for PostgreSQL, typically located at /etc/postgresql/<version>/main/postgresql.conf or /var/lib/postgres/data/postgresql.conf, depending on the platform.'
|
||||
example "
|
||||
describe postgres_conf do
|
||||
its('max_connections') { should eq '5' }
|
||||
end
|
||||
"
|
||||
|
||||
include FindFiles
|
||||
|
||||
|
|
|
@ -25,6 +25,14 @@ end
|
|||
|
||||
class PostgresSession < Inspec.resource(1)
|
||||
name 'postgres_session'
|
||||
desc 'Use the postgres_session InSpec audit resource to test SQL commands run against a PostgreSQL database.'
|
||||
example "
|
||||
sql = postgres_session('username', 'password')
|
||||
|
||||
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
|
||||
its('output') { should eq('') }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(user, pass)
|
||||
@user = user || 'postgres'
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
|
||||
class Processes < Inspec.resource(1)
|
||||
name 'processes'
|
||||
desc 'Use the processes InSpec audit resource to test properties for programs that are running on the system.'
|
||||
example "
|
||||
describe processes('mysqld') do
|
||||
its('list.length') { should eq 1 }
|
||||
end
|
||||
"
|
||||
|
||||
attr_reader :list
|
||||
def initialize(grep)
|
||||
|
|
|
@ -12,6 +12,12 @@ require 'json'
|
|||
|
||||
class RegistryKey < Inspec.resource(1)
|
||||
name 'registry_key'
|
||||
desc 'Use the registry_key InSpec audit resource to test key values in the Microsoft Windows registry.'
|
||||
example "
|
||||
describe registry_key('path\to\key') do
|
||||
its('name') { should eq 'value' }
|
||||
end
|
||||
"
|
||||
|
||||
attr_accessor :reg_key
|
||||
|
||||
|
|
|
@ -6,6 +6,16 @@
|
|||
|
||||
class Script < Cmd
|
||||
name 'script'
|
||||
desc 'Use the script InSpec audit resource to test a Windows PowerShell script on the Microsoft Windows platform.'
|
||||
example "
|
||||
script = <<-EOH
|
||||
# you powershell script
|
||||
EOH
|
||||
|
||||
describe script(script) do
|
||||
its('matcher') { should eq 'output' }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(script)
|
||||
case inspec.os[:family]
|
||||
|
|
|
@ -15,7 +15,12 @@
|
|||
|
||||
class SecurityPolicy < Inspec.resource(1)
|
||||
name 'security_policy'
|
||||
|
||||
desc 'Use the security_policy InSpec audit resource to test security policies on the Microsoft Windows platform.'
|
||||
example "
|
||||
describe security_policy do
|
||||
its('SeNetworkLogonRight') { should eq '*S-1-5-11' }
|
||||
end
|
||||
"
|
||||
def initialize
|
||||
@loaded = false
|
||||
@policy = nil
|
||||
|
|
|
@ -21,6 +21,14 @@
|
|||
# TODO: extend the logic to detect the running init system, independently of OS
|
||||
class Service < Inspec.resource(1)
|
||||
name 'service'
|
||||
desc 'Use the service InSpec audit resource to test if the named service is installed, running and/or enabled.'
|
||||
example "
|
||||
describe service('service_name') do
|
||||
it { should be_installed }
|
||||
it { should be_enabled }
|
||||
it { should be_running }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(service_name)
|
||||
@service_name = service_name
|
||||
|
|
|
@ -8,6 +8,12 @@ require 'utils/simpleconfig'
|
|||
|
||||
class SshConf < Inspec.resource(1)
|
||||
name 'ssh_config'
|
||||
desc 'Use the sshd_config InSpec audit resource to test configuration data for the Open SSH daemon located at /etc/ssh/sshd_config on Linux and UNIX platforms. sshd---the Open SSH daemon---listens on dedicated ports, starts a daemon for each incoming connection, and then handles encryption, authentication, key exchanges, command executation, and data exchanges.'
|
||||
example "
|
||||
describe sshd_config do
|
||||
its('Protocol') { should eq '2' }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(conf_path = nil, type = nil)
|
||||
@conf_path = conf_path || '/etc/ssh/ssh_config'
|
||||
|
|
|
@ -40,7 +40,14 @@ require 'utils/convert'
|
|||
|
||||
class User < Inspec.resource(1)
|
||||
name 'user'
|
||||
|
||||
desc 'Use the user InSpec audit resource to test user profiles, including the groups to which they belong, the frequency of required password changes, the directory paths to home and shell.'
|
||||
example "
|
||||
describe user('root') do
|
||||
it { should exist }
|
||||
its('uid') { should eq 1234 }
|
||||
its('gid') { should eq 1234 }
|
||||
end
|
||||
"
|
||||
def initialize(user)
|
||||
@user = user
|
||||
|
||||
|
|
|
@ -29,6 +29,12 @@
|
|||
# }
|
||||
class WindowsFeature < Inspec.resource(1)
|
||||
name 'windows_feature'
|
||||
desc 'Use the windows_feature InSpec audit resource to test features on Microsoft Windows.'
|
||||
example "
|
||||
describe windows_feature('dhcp') do
|
||||
it { should be_installed }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(feature)
|
||||
@feature = feature
|
||||
|
|
|
@ -11,6 +11,12 @@ require 'yaml'
|
|||
# end
|
||||
class YamlConfig < JsonConfig
|
||||
name 'yaml'
|
||||
desc 'Use the yaml InSpec audit resource to test configuration data in a YAML file.'
|
||||
example "
|
||||
describe yaml do
|
||||
its('name') { should eq 'foo' }
|
||||
end
|
||||
"
|
||||
|
||||
# override file load and parse hash from yaml
|
||||
def parse(content)
|
||||
|
|
|
@ -32,6 +32,13 @@ require 'resources/file'
|
|||
|
||||
class Yum < Inspec.resource(1)
|
||||
name 'yum'
|
||||
desc 'Use the yum InSpec audit resource to test packages in the Yum repository.'
|
||||
example "
|
||||
describe yum.repo('name') do
|
||||
it { should exist }
|
||||
it { should be_enabled }
|
||||
end
|
||||
"
|
||||
|
||||
# returns all repositories
|
||||
# works as following:
|
||||
|
|
Loading…
Reference in a new issue