Search code examples
rubyserverspecinspec

Check content of file with InSpec if it exists


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

Solution

  • 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