mirror of
https://github.com/inspec/inspec
synced 2024-09-20 22:41:55 +00:00
filesystem: improve Windows support (#3606)
* Improve filesystem.rb to support windows improve filesystem.rb to support windows. Split into 2 classes LinuxFileSystemResource / WindowsFileSystemResource Add filesystem to verify a FS-type ( currently not for linux because missing test server ) Size on Windows is converted to GB - discussion about this welcome update to reflect also windows os * Create get-wmiobject-filesystem * Delete get-wmiobject-filesystem * Fix the testing code for filesystem. Change its 'filesystem' to 'type' according to recommendation from @miah Signed-off-by: Markus Hackethal <mh@it31.de>
This commit is contained in:
parent
3c557eac3f
commit
86cf55382b
5 changed files with 111 additions and 34 deletions
|
@ -2,30 +2,103 @@ module Inspec::Resources
|
|||
class FileSystemResource < Inspec.resource(1)
|
||||
name 'filesystem'
|
||||
supports platform: 'linux'
|
||||
supports platform: 'windows'
|
||||
desc 'Use the filesystem InSpec resource to test file system'
|
||||
example "
|
||||
describe filesystem('/') do
|
||||
its('size') { should be >= 32000 }
|
||||
its('type') { should eq false }
|
||||
end
|
||||
describe filesystem('c:') do
|
||||
its('size') { should be >= 90 }
|
||||
its('type') { should eq 'NTFS' }
|
||||
end
|
||||
"
|
||||
attr_reader :partition
|
||||
|
||||
def initialize(partition)
|
||||
@partition = partition
|
||||
end
|
||||
@cache = nil
|
||||
# select file system manager
|
||||
@fsman = nil
|
||||
|
||||
def size
|
||||
@size ||= begin
|
||||
cmd = inspec.command("df #{partition} --output=size")
|
||||
raise Inspec::Exceptions::ResourceFailed, "Unable to get available space for partition #{partition}" if cmd.stdout.nil? || cmd.stdout.empty? || !cmd.exit_status.zero?
|
||||
|
||||
value = cmd.stdout.gsub(/\dK-blocks[\r\n]/, '').strip
|
||||
value.to_i
|
||||
os = inspec.os
|
||||
if os.linux?
|
||||
@fsman = LinuxFileSystemResource.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 if !@cache.nil?
|
||||
return {} if @fsman.nil?
|
||||
@cache = @fsman.info(@partition)
|
||||
end
|
||||
|
||||
def to_s
|
||||
"Filesystem #{partition}"
|
||||
"FileSystem #{@partition}"
|
||||
end
|
||||
|
||||
def size
|
||||
info = @fsman.info(@partition)
|
||||
info[:size]
|
||||
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 LinuxFileSystemResource < FsManagement
|
||||
def info(partition)
|
||||
cmd = inspec.command("df #{partition} --output=size")
|
||||
raise Inspec::Exceptions::ResourceFailed, "Unable to get available space for partition #{partition}" if cmd.stdout.nil? || cmd.stdout.empty? || !cmd.exit_status.zero?
|
||||
value = cmd.stdout.gsub(/\dK-blocks[\r\n]/, '').strip
|
||||
{
|
||||
name: partition,
|
||||
size: value.to_i,
|
||||
type: false,
|
||||
}
|
||||
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 / 1GB
|
||||
$disk | select -property DeviceID,Size,FileSystem | 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: fs['Size'].to_i,
|
||||
type: fs['FileSystem'],
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -547,6 +547,9 @@ class MockLoader
|
|||
|
||||
# alpine package commands
|
||||
'apk info -vv --no-network | grep git' => cmd.call('apk-info-grep-git'),
|
||||
|
||||
# filesystem command
|
||||
'2df93b941844efec1eee05c311cb4b4e8e3fd8b31808b785a70bd1a46298c716' => cmd.call('get-wmiobject-filesystem'),
|
||||
}
|
||||
|
||||
# ports on linux
|
||||
|
|
|
@ -4,10 +4,11 @@ if ENV['DOCKER']
|
|||
end
|
||||
|
||||
if os.windows?
|
||||
STDERR.puts "\033[1;33mTODO: Not running #{__FILE__.split("/").last} because we are not on Linux.\033[0m"
|
||||
return
|
||||
describe filesystem('c:') do
|
||||
its('size') { should be >= 1 }
|
||||
end
|
||||
else
|
||||
describe filesystem('/') do
|
||||
its('size') { should be >= 1 }
|
||||
end
|
||||
end
|
||||
|
||||
describe filesystem('/') do
|
||||
its('size') { should be >= 1 }
|
||||
end
|
5
test/unit/mock/cmd/get-wmiobject-filesystem
Normal file
5
test/unit/mock/cmd/get-wmiobject-filesystem
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"DeviceID": "c:",
|
||||
"Size": "100",
|
||||
"FileSystem": "NTFS"
|
||||
}
|
|
@ -2,27 +2,22 @@ require 'helper'
|
|||
require 'inspec/resource'
|
||||
|
||||
describe 'Inspec::Resources::FileSystemResource' do
|
||||
describe 'when loading filesystem in linux' do
|
||||
let (:resource) { load_resource('filesystem', '/') }
|
||||
|
||||
it 'resolves the / partition' do
|
||||
_(resource.partition).must_equal '/'
|
||||
end
|
||||
|
||||
it 'has more than 1 MB' do
|
||||
_(resource.size).must_be :>=, 1
|
||||
end
|
||||
|
||||
it 'must equal 28252316 MB' do
|
||||
_(resource.size).must_equal 28252316
|
||||
end
|
||||
# arch linux
|
||||
it 'verify filesystem on linux' do
|
||||
resource = MockLoader.new(:ubuntu1404).load_resource('filesystem','/')
|
||||
_(resource.size).must_be :>=, 1
|
||||
_(resource.name).must_equal '/'
|
||||
end
|
||||
|
||||
# arch windows
|
||||
it 'verify filesystem on windows' do
|
||||
resource = MockLoader.new(:windows).load_resource('filesystem','c:')
|
||||
_(resource.size).must_be :>=, 1
|
||||
_(resource.name).must_equal 'c:'
|
||||
end
|
||||
describe 'when loading filesystem in unsupported OS family' do
|
||||
it 'fails on Windows' do
|
||||
resource_fail = MockLoader.new(:windows).load_resource('filesystem', '/')
|
||||
resource_fail.check_supports.must_equal false
|
||||
end
|
||||
|
||||
# unsuported os
|
||||
describe 'when loading filesystem in unsupported OS family' do
|
||||
it 'fails on FreeBSD (unix-like)' do
|
||||
resource_fail = MockLoader.new(:freebsd10).load_resource('filesystem', '/')
|
||||
resource_fail.check_supports.must_equal false
|
||||
|
|
Loading…
Reference in a new issue