4

I'm writing a Chef InSpec test in ruby to check the contents of the files for 'umask 077'. The issue is that for a few of the files in my array that I'm checking for do not exist. I'm trying to exclude nil files and re-push them, but it seems to attempt to check all of the files anyway. Any thoughts?

Here is my code:

control 'auth-default-umask' do
  impact 0.5
  title 'Default umask'
  desc 'DISA RHEL6 STIG (V1R2)'

  %w(/etc/profile /etc/bashrc /etc/csh.login /etc/.login).each do |umask_file|
    filecheck = []
    unless umask_file == nil
      filecheck.push(umask_file)
      describe directory(filecheck) do
        its('content') { should match /umask 077/ }
      end
    end
  end
end
techraf
  • 64,883
  • 27
  • 193
  • 198
Blooze
  • 1,987
  • 4
  • 16
  • 19

2 Answers2

3

You're checking if the file name is nil, which it never is, so naturally it runs all those times. Are you trying to exclude the file if it doesn't exist?

Also, You probably wanted to describe the directory and not the list of directories, so notice I changed that too.

Here's the finalized result:

control 'auth-default-umask' do
  impact 0.5
  title 'Default umask'
  desc 'DISA RHEL6 STIG (V1R2)'

  %w(/etc/profile /etc/bashrc /etc/csh.login /etc/.login).each do |umask_file|
    filecheck = []
    if File.exists?(umask_file)  # check file existence
      filecheck.push(umask_file)
      describe directory(umask_file) do  # describe this directory
        its('content') { should match /umask 077/ }
      end
    end
  end
end

What you did correctly is create an array of filenames using %w(), which simply takes each word inside it and makes an array of strings (of the paths you input). These alone have no meaning, but they can be used with classes, such as File, to become meaningful in a filesystem context.

File.exists?(filename) checks whether a file exists, for example.

To read a file, you can use File.open:

File.open(filename, 'r') do |file|
  until file.eof?
    line = file.gets
    # do something with line
  end
end
casraf
  • 21,085
  • 9
  • 56
  • 91
  • @Blooze It is holding all of the files that exist. Functionally, it is not actually doing anything useful now and can be safely removed from the code. @Casraf This question is not actually Chef related, and `describe directory` should really be `describe file` (although it probably still works as is with the RSpec matchers, `file` is the preferred Serverspec usage for this). – Matthew Schuchard Nov 07 '16 at 17:39
1

The if File.exists?(umask_file) method works against the local system. If Inspec is used with the --target option this method will probably not work as expected since the follow-up checks will be run against the target after performing the existence check locally.

An alternative syntax which tests the file existence on the target side would be:

control 'example-control-name' do
  only_if { file('/path/to/file').exist? }
  describe file('/path/to/file') do
    its('content') { should match /desired-content-here/ }
  end
end
Steve Bonds
  • 221
  • 3
  • 5