# 8. Inspec Examples

# 8.1 rspec Explicit Subject

Here we have a inspec test that lists out it's current directory. Our original test code looks like this

describe command('ls -al').stdout.strip do
  it { should_not be_empty }
end
1
2
3

If we would like to have a more Explicit Subject (opens new window) then we could refactor the code like this example

describe "this is a detailed message" do
  subject { command('ls -al').stdout.strip }
  it{ should_not be_empty }
end
1
2
3
4

# 8.2 Looping

For looping through a file directory, the directory resource is not powerful enough to do that, so we are required to use the command resource and run a find or it's equivalent for your target OS. This can be very resource intensive on your target so try to be as specific as possible with your search such as the example below:

command('find ~/* -type f -maxdepth 0 -xdev').stdout.split.each do |fname|
  describe file(fname) do
    its('owner') { should cmp 'ec2-user' }
  end
end
1
2
3
4
5

# 8.3 The “should” vs. “expect” syntax

Users familiar with the RSpec testing framework may know that there are two ways to write test statements: should and expect. The RSpec community decided that expect is the preferred syntax.

InSpec recommends the should syntax as it tends to read more easily to those users who are not as technical, however there are times when the expect syntax will communicate much more clearly to the end-user.

InSpec will continue to support both methods of writing tests. Consider this file test:

describe file('/tmp/test.txt') do
  it { should be_file }
end
1
2
3

This can be re-written with expect syntax

describe file('/tmp/test.txt') do
  it 'should be a file' do
    expect(subject).to(be_file)
  end
end
1
2
3
4
5

The output of both of the above examples looks like this:

File /tmp/test.txt
   ✔  should be a file
1
2

In addition, you can make use of the subject keyword to further control your output if you choose:

describe 'test file' do
  subject { file('/tmp/test.txt') }
  it 'should be a file' do
    expect(subject).to(be_file)
  end
end
1
2
3
4
5
6

… which will render the following output:

test file
  ✔  should be a fill
1
2

Reference: https://docs.chef.io/inspec/profiles/ (opens new window)

# 8.4 Expect syntax and Password Hashes

Here we have an inspec test that checks if passwords are SHA512 hashes. As a quick thought exercise can you think of how we can adjust the control below to support SHA512 or higher assuming where you are testing uses SHA1024 or even SHA2048?

bad_users = inspec.shadow.where { password != "*" && password != "!" && password !~ /\$6\$/ }.users

describe 'Password hashes in /etc/shadow' do
  it 'should only contain SHA512 hashes' do
    failure_message = "Users without SHA512 hashes: #{bad_users.join(', ')}"
    expect(bad_users).to be_empty, failure_message
  end
end
1
2
3
4
5
6
7
8