Merge pull request #3778 from inspec/team/filesystem-free-percent

filesystem: Add free_kb, size_kb, type, and percent_free properties
This commit is contained in:
Clinton Wolfe 2019-02-06 17:40:10 -05:00 committed by GitHub
commit 48711fa7bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 26 deletions

View file

@ -19,18 +19,29 @@ This resource is distributed along with InSpec itself. You can use it automatica
This resource first became available in v1.51.0 of InSpec.
The `free_kb`, `size_kb`, and `type` properties became available in v3.6 of InSpec.
### Note
Versions of this resource in InSpec prior to 3.5.x offered a property `size`, which returned a value in GB when on Windows and a value in KB on Linux, though it was documented to always return KB. All new code should use `size_kb` which is unit-stable. The property `size` will remain available in InSpec v3 and 4, but will be deprecated in the future.
## Syntax
A `filesystem` resource block declares tests for disk space in a partition:
describe filesystem('/') do
its('size') { should be >= 32000 }
its('size_kb') { should be >= 32 * 1024 * 1024}
its('free_kb') { should be >= 50 * 1024 }
its('percent_free') { should be >= 20 }
its('type') { should cmp 'ext4' }
end
where
* `filesystem('/')` states that the resource will look at the root (/) partition.
* `size` is measured in kilobytes (KB).
* `size_kb` is the total partition size and is measured in kilobytes (KB).
* `free_kb` is the available space on the partition and is measured in kilobytes (KB).
* `percent_free` is the percentage of available free space, and ranges from 0 to 100.
<br>
@ -41,11 +52,33 @@ The following examples show how to use this InSpec audit resource.
### Test if the root partition is greater than 32000 KB
describe filesystem('/') do
its('size') { should be >= 32000 }
its('size_kb') { should be >= 32000 }
end
<br>
### Test that the root partition has more than 5GB free
describe filesystem('/') do
its('free_kb') { should be >= 5000000 }
end
<br>
### Test if the C:\ partition is NTFS
describe filesystem('c:\') do
its('type') { should cmp 'NTFS' }
end
<br>
### Test if the /var partition has sufficient free space
describe filesystem('/var') do
its('percent_free') { should be >= 20 }
end
## Matchers
For a full list of available matchers, please visit our [matchers page](https://www.inspec.io/docs/reference/matchers/).

View file

@ -10,6 +10,10 @@
"action": "ignore",
"prefix": "The --json-config option is being replaced by the --config option.",
"comment": "See #3661"
},
"filesystem_property_size": {
"action": "ignore",
"comment": "See #3778"
}
}
}

View file

@ -6,12 +6,16 @@ module Inspec::Resources
desc 'Use the filesystem InSpec resource to test file system'
example "
describe filesystem('/') do
its('size') { should be >= 32000 }
its('type') { should eq false }
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') { should be >= 90 }
its('type') { should eq 'NTFS' }
its('size_kb') { should be >= 9000 }
its('free_kb') { should be >= 3200 }
its('type') { should cmp 'NTFS' }
its('percent_free') { should be >= 20 }
end
"
attr_reader :partition
@ -42,9 +46,30 @@ module Inspec::Resources
"FileSystem #{@partition}"
end
def size
def size_kb
info = @fsman.info(@partition)
info[:size]
info[:size_kb]
end
def size
Inspec.deprecate(:filesystem_property_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
@ -67,13 +92,14 @@ module Inspec::Resources
class LinuxFileSystemResource < FsManagement
def info(partition)
cmd = inspec.command("df #{partition} --output=size")
cmd = inspec.command("df #{partition} -T")
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 = cmd.stdout.split(/\n/)[1].strip.split(' ')
{
name: partition,
size: value.to_i,
type: false,
size_kb: value[2].to_i,
free_kb: value[4].to_i,
type: value[1].to_s,
}
end
end
@ -82,8 +108,9 @@ module Inspec::Resources
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
$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
@ -96,7 +123,8 @@ module Inspec::Resources
end
{
name: fs['DeviceID'],
size: fs['Size'].to_i,
size_kb: fs['Size'].to_i,
free_kb: fs['FreeSpace'].to_i,
type: fs['FileSystem'],
}
end

View file

@ -425,7 +425,7 @@ class MockLoader
'/sbin/zpool get -Hp all tank' => cmd.call('zpool-get-all-tank'),
# docker
"4f8e24022ea8b7d3b117041ec32e55d9bf08f11f4065c700e7c1dc606c84fd17" => cmd.call('docker-ps-a'),
"9ef45813d4545f35d6fe9d6456c0b1063f9f5a80c699d3bb19da0699ab2d6ecc" => cmd.call('df'),
"b40ed61c006b54f155b28a85dc944dc0352b30222087b47c6279568ec0e59d05" => cmd.call('df-t'),
"docker version --format '{{ json . }}'" => cmd.call('docker-version'),
"docker info --format '{{ json . }}'" => cmd.call('docker-info'),
"docker inspect 71b5df59442b" => cmd.call('docker-inspec'),
@ -551,7 +551,7 @@ class MockLoader
'apk info -vv --no-network | grep git' => cmd.call('apk-info-grep-git'),
# filesystem command
'2df93b941844efec1eee05c311cb4b4e8e3fd8b31808b785a70bd1a46298c716' => cmd.call('get-wmiobject-filesystem'),
'2e7e0d4546342cee799748ec7e2b1c87ca00afbe590fa422a7c27371eefa88f0' => cmd.call('get-wmiobject-filesystem'),
}
# ports on linux

View file

@ -1 +0,0 @@
28252316

2
test/unit/mock/cmd/df-t Normal file
View file

@ -0,0 +1,2 @@
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/sda1 ext4 30428648 9651536 20760728 32% /

View file

@ -1,5 +1,6 @@
{
"DeviceID": "c:",
"Size": "100",
"FileSystem": "NTFS"
"Size": "40000000",
"FileSystem": "NTFS",
"FreeSpace": "30000000"
}

View file

@ -4,16 +4,24 @@ require 'inspec/resource'
describe 'Inspec::Resources::FileSystemResource' do
# arch linux
it 'verify filesystem on linux' do
resource = MockLoader.new(:ubuntu1404).load_resource('filesystem','/')
_(resource.size).must_be :>=, 1
resource = MockLoader.new(:ubuntu1404).load_resource('filesystem','/')
_(resource.size_kb).must_equal 30428648
_(resource.size).must_equal 30428648
_(resource.name).must_equal '/'
_(resource.type).must_equal 'ext4'
_(resource.free_kb).must_equal 20760728
_(resource.percent_free).must_equal 68
end
# arch windows
# windows
it 'verify filesystem on windows' do
resource = MockLoader.new(:windows).load_resource('filesystem','c:')
_(resource.size).must_be :>=, 1
_(resource.size).must_equal 38 # Windows size() had a bug that turned it into GB, not KB
_(resource.size_kb).must_equal 40000000 # approx 38 GB
_(resource.name).must_equal 'c:'
_(resource.type).must_equal 'NTFS'
_(resource.free_kb).must_equal 30000000
_(resource.percent_free).must_equal 75
end
# unsuported os