File Manager
Viewing File: filesystem.rb
require "inspec/resources/command"
module Inspec::Resources
class FileSystemResource < Inspec.resource(1)
name "filesystem"
supports platform: "unix"
supports platform: "windows"
desc "Use the filesystem InSpec resource to test file system"
example <<~EXAMPLE
describe filesystem('/') do
its('size_kb') { should be >= 32000 }
its('free_kb') { should be >= 3200 }
its('type') { should cmp 'ext4' }
its('percent_free') { should be >= 20 }
end
describe filesystem('c:') do
its('size_kb') { should be >= 9000 }
its('free_kb') { should be >= 3200 }
its('type') { should cmp 'NTFS' }
its('percent_free') { should be >= 20 }
end
EXAMPLE
attr_reader :partition
def initialize(partition)
@partition = partition
@cache = nil
# select file system manager
@fsman = nil
os = inspec.os
if os.unix?
@fsman = UnixFileSystemResource.new(inspec)
elsif os.windows?
@fsman = WindowsFileSystemResource.new(inspec)
else
raise Inspec::Exceptions::ResourceSkipped, "The `filesystem` resource is not supported on your OS yet."
end
end
def info
return @cache unless @cache.nil?
return {} if @fsman.nil?
@cache = @fsman.info(@partition)
end
def to_s
"FileSystem #{@partition}"
end
def size_kb
info = @fsman.info(@partition)
info[:size_kb]
end
def size
Inspec.deprecate(:property_filesystem_size, "The `size` property did not reliably use the correct units. Please use `size_kb` instead.")
if inspec.os.windows?
# On windows, we had a bug prior to #3767 in which the
# 'size' value was be scaled to GB in powershell.
# We now collect it in KB.
(size_kb / (1024 * 1024)).to_i
else
size_kb
end
end
def free_kb
info = @fsman.info(@partition)
info[:free_kb]
end
def percent_free
100 * free_kb / size_kb
end
def type
info = @fsman.info(@partition)
info[:type]
end
def name
info = @fsman.info(@partition)
info[:name]
end
end
class FsManagement
attr_reader :inspec
def initialize(inspec)
@inspec = inspec
end
end
class UnixFileSystemResource < FsManagement
def info(partition)
cmd = inspec.command("df #{partition} -PT")
if cmd.stdout.nil? || cmd.stdout.empty? || cmd.exit_status != 0
raise Inspec::Exceptions::ResourceFailed,
"Unable to get available space for partition #{partition}"
end
value = cmd.stdout.split(/\n/)[1].strip.split(" ")
{
name: partition,
size_kb: value[2].to_i,
free_kb: value[4].to_i,
type: value[1].to_s,
}
end
end
class WindowsFileSystemResource < FsManagement
def info(partition)
cmd = inspec.command <<-EOF.gsub(/^\s*/, "")
$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='#{partition}'"
$disk.Size = $disk.Size / 1KB
$disk.FreeSpace = $disk.FreeSpace / 1KB
$disk | select -property DeviceID,Size,FileSystem,FreeSpace | ConvertTo-Json
EOF
raise Inspec::Exceptions::ResourceSkipped, "Unable to get available space for partition #{partition}" if cmd.stdout == "" || cmd.exit_status.to_i != 0
begin
fs = JSON.parse(cmd.stdout)
rescue JSON::ParserError => e
raise Inspec::Exceptions::ResourceFailed,
"Failed to parse JSON from Powershell. " \
"Error: #{e}"
end
{
name: fs["DeviceID"],
size_kb: fs["Size"].to_i,
free_kb: fs["FreeSpace"].to_i,
type: fs["FileSystem"],
}
end
end
end