inspec 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +24 -2
- data/bin/inspec +5 -2
- data/lib/bundles/inspec-init.rb +8 -0
- data/lib/bundles/inspec-init/cli.rb +86 -0
- data/lib/bundles/inspec-init/templates/profile/README.md +3 -0
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +20 -0
- data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -0
- data/lib/bundles/inspec-init/templates/profile/libraries/.gitkeep +0 -0
- data/lib/inspec/targets/archive.rb +14 -24
- data/lib/inspec/targets/core.rb +37 -8
- data/lib/inspec/targets/dir.rb +115 -52
- data/lib/inspec/targets/folder.rb +14 -29
- data/lib/inspec/targets/tar.rb +11 -13
- data/lib/inspec/targets/zip.rb +7 -7
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/iptables.rb +11 -14
- data/lib/resources/service.rb +76 -12
- data/test/integration/cookbooks/os_prepare/recipes/default.rb +1 -0
- data/test/integration/cookbooks/os_prepare/recipes/iptables.rb +13 -0
- data/test/integration/test/integration/default/iptables_spec.rb +25 -0
- data/test/unit/mock/cmd/iptables-s +1 -1
- data/test/unit/resources/iptables_test.rb +5 -0
- data/test/unit/resources/service_test.rb +46 -4
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e3b076ffed41d9148eb98065a025a6acb6a9f70
|
4
|
+
data.tar.gz: eb36dc73cf37bc30a46949943ba7db582ed82417
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 09d87d6da242d31586af6d3e39e913223a141d6dbc39474c921636d3169a57bcf1b5029defc1d2f6a8f01c246fe3494846edfe9d00a27381f3aa13f8f335435a
|
7
|
+
data.tar.gz: d2806a4c8e637a1ec46cf3ed9ea5a40fc8dd32a6e3bb0de63f405d33f4de9a09d3f25faf36932d949b73c7d9ff1d11949e59963f6ab6116402890632facb0227
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,27 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [0.
|
4
|
-
[Full Changelog](https://github.com/chef/inspec/compare/v0.
|
3
|
+
## [0.12.0](https://github.com/chef/inspec/tree/0.12.0) (2016-02-15)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.11.0...0.12.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- add runlevel support for System V services [\#455](https://github.com/chef/inspec/pull/455) ([arlimus](https://github.com/arlimus))
|
9
|
+
- Add a init subcommand [\#454](https://github.com/chef/inspec/pull/454) ([chris-rock](https://github.com/chris-rock))
|
10
|
+
|
11
|
+
**Fixed bugs:**
|
12
|
+
|
13
|
+
- Windows 2008 isn't being detected. [\#346](https://github.com/chef/inspec/issues/346)
|
14
|
+
- Fix two minor logging and config bugs in CLI [\#452](https://github.com/chef/inspec/pull/452) ([srenatus](https://github.com/srenatus))
|
15
|
+
- bugfix: verify the target resolver before using it [\#449](https://github.com/chef/inspec/pull/449) ([arlimus](https://github.com/arlimus))
|
16
|
+
- Fix iptables on CentOS6 + more tests for iptables \(plus small code improvements\) [\#442](https://github.com/chef/inspec/pull/442) ([srenatus](https://github.com/srenatus))
|
17
|
+
|
18
|
+
**Merged pull requests:**
|
19
|
+
|
20
|
+
- rework target to resolver connection [\#447](https://github.com/chef/inspec/pull/447) ([arlimus](https://github.com/arlimus))
|
21
|
+
- separate directory resolver from target resolver [\#446](https://github.com/chef/inspec/pull/446) ([arlimus](https://github.com/arlimus))
|
22
|
+
|
23
|
+
## [v0.11.0](https://github.com/chef/inspec/tree/v0.11.0) (2016-02-10)
|
24
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.10.1...v0.11.0)
|
5
25
|
|
6
26
|
**Implemented enhancements:**
|
7
27
|
|
@@ -11,12 +31,14 @@
|
|
11
31
|
**Fixed bugs:**
|
12
32
|
|
13
33
|
- File stats are not always working properly [\#430](https://github.com/chef/inspec/issues/430)
|
34
|
+
- Inspec iptables should have\_rule tests not working [\#420](https://github.com/chef/inspec/issues/420)
|
14
35
|
- Integration test for apache config [\#406](https://github.com/chef/inspec/issues/406)
|
15
36
|
- rework auditd\_rules resource [\#312](https://github.com/chef/inspec/issues/312)
|
16
37
|
- resource/auditd\_rules: update rule list format [\#309](https://github.com/chef/inspec/issues/309)
|
17
38
|
|
18
39
|
**Merged pull requests:**
|
19
40
|
|
41
|
+
- 0.11.0 [\#443](https://github.com/chef/inspec/pull/443) ([arlimus](https://github.com/arlimus))
|
20
42
|
- Fix supermarket cli registration [\#441](https://github.com/chef/inspec/pull/441) ([chris-rock](https://github.com/chris-rock))
|
21
43
|
- update to winrm 1.6.1 command scheme [\#439](https://github.com/chef/inspec/pull/439) ([arlimus](https://github.com/arlimus))
|
22
44
|
- semantics: rename CLI plugins registry -\> commands [\#435](https://github.com/chef/inspec/pull/435) ([arlimus](https://github.com/arlimus))
|
data/bin/inspec
CHANGED
@@ -84,7 +84,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
84
84
|
def archive(path)
|
85
85
|
diagnose
|
86
86
|
|
87
|
-
o =
|
87
|
+
o = opts.dup
|
88
88
|
o[:logger] = Logger.new(STDOUT)
|
89
89
|
o[:logger].level = get_log_level(o.log_level)
|
90
90
|
|
@@ -129,8 +129,11 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
129
129
|
option :format, type: :string, default: Inspec::NoSummaryFormatter, hide: true
|
130
130
|
def shell_func
|
131
131
|
diagnose
|
132
|
+
o = opts.dup
|
133
|
+
o[:logger] = Logger.new(STDOUT)
|
134
|
+
o[:logger].level = get_log_level(o.log_level)
|
132
135
|
|
133
|
-
runner = Inspec::Runner.new(
|
136
|
+
runner = Inspec::Runner.new(o)
|
134
137
|
Inspec::Shell.new(runner).start
|
135
138
|
rescue RuntimeError => e
|
136
139
|
puts e.message
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
|
4
|
+
module Init
|
5
|
+
class CLI < Inspec::BaseCLI
|
6
|
+
namespace 'init'
|
7
|
+
|
8
|
+
# read template directoy
|
9
|
+
template_dir = File.join(File.dirname(__FILE__), 'templates')
|
10
|
+
Dir.glob(File.join(template_dir, '*')) do |template|
|
11
|
+
relative = Pathname.new(template).relative_path_from(Pathname.new(template_dir))
|
12
|
+
|
13
|
+
# register command for the template
|
14
|
+
desc "#{relative} NAME", "Create a new #{relative}"
|
15
|
+
option :overwrite, type: :boolean, default: false,
|
16
|
+
desc: 'Overwrites existing directory'
|
17
|
+
define_method relative.to_s.to_sym do |name|
|
18
|
+
generator(relative.to_s, { name: name }, options)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# 1. iterate over all files
|
25
|
+
# 2. read content in erb
|
26
|
+
# 3. write to target
|
27
|
+
def generator(type, attributes = {}, options = {}) # rubocop:disable Metrics/AbcSize
|
28
|
+
# path of this script
|
29
|
+
dir = File.dirname(__FILE__)
|
30
|
+
# look for template directory
|
31
|
+
base_dir = File.join(dir, 'templates', type)
|
32
|
+
# prepare glob for all subdirectories and files
|
33
|
+
template = File.join(base_dir, '**', '{*,.*}')
|
34
|
+
# generate target path
|
35
|
+
target = Pathname.new(Dir.pwd).join(attributes[:name])
|
36
|
+
puts "Create new #{type} at #{mark_text(target)}"
|
37
|
+
|
38
|
+
# check that the directory does not exist
|
39
|
+
if File.exist?(target) && !options['overwrite']
|
40
|
+
error "#{mark_text(target)} exists already, use --overwrite"
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
# ensure that target directory is available
|
45
|
+
FileUtils.mkdir_p(target)
|
46
|
+
|
47
|
+
# iterate over files and write to target path
|
48
|
+
Dir.glob(template) do |file|
|
49
|
+
relative = Pathname.new(file).relative_path_from(Pathname.new(base_dir))
|
50
|
+
destination = Pathname.new(target).join(relative)
|
51
|
+
if File.directory?(file)
|
52
|
+
li "Create directory #{mark_text(relative)}"
|
53
|
+
FileUtils.mkdir_p(destination)
|
54
|
+
elsif File.file?(file)
|
55
|
+
li "Create file #{mark_text(relative)}"
|
56
|
+
# read & render content
|
57
|
+
content = render(File.read(file), attributes)
|
58
|
+
# write file content
|
59
|
+
File.write(destination, content)
|
60
|
+
else
|
61
|
+
puts "Ignore #{file}, because its not an file or directoy"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# This is a render helper to bind hash values to a ERB template
|
67
|
+
def render(content, hash)
|
68
|
+
# create a new binding class
|
69
|
+
cls = Class.new do
|
70
|
+
hash.each do |key, value|
|
71
|
+
define_method key.to_sym do
|
72
|
+
value
|
73
|
+
end
|
74
|
+
end
|
75
|
+
# expose binding
|
76
|
+
define_method :bind do
|
77
|
+
binding
|
78
|
+
end
|
79
|
+
end
|
80
|
+
ERB.new(content).result(cls.new.bind)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# register the subcommand to Inspec CLI registry
|
85
|
+
Inspec::Plugins::CLI.add_subcommand(Init::CLI, 'init', 'init TEMPLATE ...', 'Scaffolds a new project', {})
|
86
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# copyright: 2015, The Authors
|
3
|
+
# license: All rights reserved
|
4
|
+
|
5
|
+
title 'sample section'
|
6
|
+
|
7
|
+
# you can also use plain tests
|
8
|
+
describe file('/tmp') do
|
9
|
+
it { should be_directory }
|
10
|
+
end
|
11
|
+
|
12
|
+
# you add controls here
|
13
|
+
control 'tmp-1.0' do # A unique ID for this control
|
14
|
+
impact 0.7 # The criticality, if this control fails.
|
15
|
+
title 'Create /tmp directory' # A human-readable title
|
16
|
+
desc 'An optional description...'
|
17
|
+
describe file('/tmp') do # The actual test
|
18
|
+
it { should be_directory }
|
19
|
+
end
|
20
|
+
end
|
File without changes
|
@@ -4,40 +4,30 @@
|
|
4
4
|
|
5
5
|
require 'rubygems/package'
|
6
6
|
require 'zlib'
|
7
|
+
require 'inspec/targets/dir'
|
7
8
|
|
8
9
|
module Inspec::Targets
|
9
|
-
class ArchiveHelper
|
10
|
-
|
11
|
-
|
10
|
+
class ArchiveHelper < DirsResolver
|
11
|
+
attr_reader :files
|
12
|
+
|
13
|
+
def initialize(target, _opts = {})
|
14
|
+
@target = target
|
15
|
+
files, @rootdir = structure(target)
|
12
16
|
|
13
17
|
# remove trailing slashes
|
14
18
|
files = files.collect { |f| f.chomp('/') }
|
15
19
|
|
16
20
|
# remove leading directory
|
17
|
-
|
18
|
-
|
21
|
+
root = Pathname(@rootdir)
|
22
|
+
@files = files.collect { |f|
|
23
|
+
Pathname(f).relative_path_from(root).to_s
|
19
24
|
}
|
20
|
-
|
21
|
-
helper = DirsHelper.get_handler(files)
|
22
|
-
if helper.nil?
|
23
|
-
fail "Don't know how to handle folder #{target}"
|
24
|
-
end
|
25
|
-
|
26
|
-
res = {
|
27
|
-
test: collect(helper, files, :get_filenames),
|
28
|
-
library: collect(helper, files, :get_libraries),
|
29
|
-
metadata: collect(helper, files, :get_metadata),
|
30
|
-
}.map { |as, list|
|
31
|
-
content(target, list, rootdir, base_folder: target, as: as)
|
32
|
-
}
|
33
|
-
|
34
|
-
res.flatten
|
35
25
|
end
|
36
26
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
27
|
+
def resolve(path, opts = {})
|
28
|
+
o = (opts || {})
|
29
|
+
o[:base_folder] = @target
|
30
|
+
content(@target, path, @rootdir, o)
|
41
31
|
end
|
42
32
|
end
|
43
33
|
end
|
data/lib/inspec/targets/core.rb
CHANGED
@@ -8,18 +8,47 @@ module Inspec
|
|
8
8
|
module Targets
|
9
9
|
extend Modulator
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# Retrieve the resolver for a given target. Resolvers are any type of
|
12
|
+
# instance, that can take a target in the #resolve method, and turn
|
13
|
+
# it into raw InSpec code. It will actually retrieve all file's
|
14
|
+
# contents, including libraries and metadata.
|
15
|
+
#
|
16
|
+
# @param [any] target any target you are pointing to; typically a string
|
17
|
+
# @return [Inspec::Targets::*] the resolver handling this target
|
18
|
+
def self.find_resolver(target)
|
19
|
+
modules.values.find { |m| m.handles?(target) }
|
20
|
+
end
|
21
|
+
|
22
|
+
# Retrieve the target handler, i.e. the component that is going to handle
|
23
|
+
# all aspects of a given target. Unlike the resolver, this provides
|
24
|
+
# access to an object, that understands the target and is able to read
|
25
|
+
# all contents, while providing additional methods which InSpec itself
|
26
|
+
# does not care about (think: plugins).
|
27
|
+
#
|
28
|
+
# There is a special case, where you might be pointing to a URL containing
|
29
|
+
# a ZIP file which has a full InSpec Profile embedded. This will be
|
30
|
+
# resolved to a directory helper (Inspec::Targets::DirsResolver). This
|
31
|
+
# method will retrieve the right handler for this directory and provide it
|
32
|
+
# with full access all contents (i.e. the DirsResolver will be embedded).
|
33
|
+
#
|
34
|
+
# @param [any] target any target you are pointing to; typically a string
|
35
|
+
# @return [Inspec::Targets::*] the handler for this target
|
36
|
+
def self.find_handler(target)
|
37
|
+
resolver = find_resolver(target)
|
38
|
+
return resolver unless resolver.is_a?(Module) &&
|
39
|
+
resolver.ancestors.include?(DirsResolver)
|
40
|
+
resolver.from_target(target).handler
|
15
41
|
end
|
16
42
|
|
43
|
+
# Turn targets into actionable InSpec code, library-data and metadata.
|
44
|
+
#
|
45
|
+
# @param [any] targets any targets you are pointing to; typically strings
|
46
|
+
# @param [Hash] additional options for loading
|
47
|
+
# @return [Array] an array of resolved data, with :content, :ref, :type
|
17
48
|
def self.resolve(targets, opts = {})
|
18
49
|
Array(targets).map do |target|
|
19
|
-
handler =
|
20
|
-
|
21
|
-
fail "Don't know how to handle target: #{target}"
|
22
|
-
end
|
50
|
+
handler = find_resolver(target) ||
|
51
|
+
fail("Don't know how to handle target: #{target}")
|
23
52
|
handler.resolve(target, opts)
|
24
53
|
end.flatten
|
25
54
|
end
|
data/lib/inspec/targets/dir.rb
CHANGED
@@ -3,79 +3,142 @@
|
|
3
3
|
# author: Christoph Hartmann
|
4
4
|
|
5
5
|
module Inspec::Targets
|
6
|
+
# DirsHelper manages resolvers for directories. Wherever directories are,
|
7
|
+
# either a local folder, archive, or remote, this module provides all helpers
|
8
|
+
# than can resolve these.
|
9
|
+
#
|
10
|
+
# Resolvers provide these methods
|
11
|
+
# * handles?(paths) => true if the resolver is responsible for this target
|
12
|
+
# * get_filenames => Array[String] of files where tests/controls are found
|
13
|
+
# * get_metadata => String path with metadata information [optional]
|
14
|
+
# * get_libraries => Array[String] of library files [optional]
|
15
|
+
#
|
16
|
+
# Resolvers must register with this DirsHelper via #add_module .
|
6
17
|
module DirsHelper
|
7
|
-
|
8
|
-
# Previous versions used the `test` directory instead of the new `controls`
|
9
|
-
# directory. Usage of the test directory is deprecated and not recommended
|
10
|
-
# anymore. Support for `test` will be removed in InSpec 1.0
|
11
|
-
# TODO: remove `test` support for InSpec 1.0
|
12
|
-
class ProfileDir
|
13
|
-
def handles?(paths)
|
14
|
-
return true if paths.include?('inspec.yml')
|
15
|
-
(
|
16
|
-
!paths.grep(/^controls/).empty? ||
|
17
|
-
!paths.grep(/^test/).empty?
|
18
|
-
) && paths.include?('metadata.rb')
|
19
|
-
end
|
18
|
+
extend Modulator
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
20
|
+
def self.get_handler(paths)
|
21
|
+
modules.values.reverse.find { |x| x.handles?(paths) }
|
22
|
+
end
|
23
|
+
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
# Base class for all directory resolvers. I.e. any target helper that
|
26
|
+
# takes a directory/archive/... and ultimately calls DirsHelper to resolve it.
|
27
|
+
#
|
28
|
+
# These resolvers must implement the required methods of this class.
|
29
|
+
class DirsResolver
|
30
|
+
def files
|
31
|
+
fail NotImplementedError, "Directory resolver #{self.class} must implement #files"
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
return 'metadata.rb' if paths.include?('metadata.rb')
|
36
|
-
end
|
34
|
+
def resolve(_path)
|
35
|
+
fail NotImplementedError, "Directory resolver #{self.class} must implement #content"
|
37
36
|
end
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
def handler
|
39
|
+
DirsHelper.get_handler(files) ||
|
40
|
+
fail("Don't know how to handle #{self}")
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.from_target(target)
|
44
|
+
new(target)
|
45
|
+
end
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
47
|
+
def self.resolve(target, opts)
|
48
|
+
r = new(target, opts)
|
49
|
+
handler = r.handler
|
50
|
+
files = r.files
|
51
|
+
|
52
|
+
res = []
|
53
|
+
{
|
54
|
+
test: __collect(handler, :get_filenames, files),
|
55
|
+
library: __collect(handler, :get_libraries, files),
|
56
|
+
metadata: __collect(handler, :get_metadata, files),
|
57
|
+
}.each do |as, list|
|
58
|
+
Array(list).each { |path|
|
59
|
+
res.push(r.resolve(path, as: as))
|
60
|
+
}
|
48
61
|
end
|
62
|
+
|
63
|
+
return handler.resolve_contents(res) if handler.respond_to?(:resolve_contents)
|
64
|
+
res
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.__collect(handler, getter, files)
|
68
|
+
return [] unless handler.respond_to? getter
|
69
|
+
handler.method(getter).call(files)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# InSpec profile Loader
|
74
|
+
# Previous versions used the `test` directory instead of the new `controls`
|
75
|
+
# directory. Usage of the test directory is deprecated and not recommended
|
76
|
+
# anymore. Support for `test` will be removed in InSpec 1.0
|
77
|
+
# TODO: remove `test` support for InSpec 1.0
|
78
|
+
class ProfileDir
|
79
|
+
def handles?(paths)
|
80
|
+
return true if paths.include?('inspec.yml')
|
81
|
+
(
|
82
|
+
!paths.grep(/^controls/).empty? ||
|
83
|
+
!paths.grep(/^test/).empty?
|
84
|
+
) && paths.include?('metadata.rb')
|
49
85
|
end
|
50
86
|
|
51
|
-
|
52
|
-
|
53
|
-
|
87
|
+
def get_libraries(paths)
|
88
|
+
paths.find_all do |path|
|
89
|
+
path.start_with?('libraries') && path.end_with?('.rb')
|
54
90
|
end
|
91
|
+
end
|
55
92
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
93
|
+
def get_filenames(paths)
|
94
|
+
paths.find_all do |path|
|
95
|
+
path.start_with?('controls', 'test') && path.end_with?('.rb')
|
60
96
|
end
|
61
97
|
end
|
62
98
|
|
63
|
-
|
64
|
-
|
65
|
-
|
99
|
+
def get_metadata(paths)
|
100
|
+
return 'inspec.yml' if paths.include?('inspec.yml')
|
101
|
+
return 'metadata.rb' if paths.include?('metadata.rb')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
DirsHelper.add_module('inspec-profile', ProfileDir.new)
|
105
|
+
|
106
|
+
class ChefAuditDir
|
107
|
+
def handles?(paths)
|
108
|
+
paths.include?('recipes') and paths.include?('metadata.rb')
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_filenames(paths)
|
112
|
+
paths.find_all do |x|
|
113
|
+
x.start_with? 'recipes/' and x.end_with? '.rb'
|
66
114
|
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
DirsHelper.add_module('chef-cookbook', ChefAuditDir.new)
|
118
|
+
|
119
|
+
class ServerspecDir
|
120
|
+
def handles?(paths)
|
121
|
+
paths.include?('spec')
|
122
|
+
end
|
67
123
|
|
68
|
-
|
69
|
-
|
124
|
+
def get_filenames(paths)
|
125
|
+
paths.find_all do |path|
|
126
|
+
path.start_with? 'spec' and path.end_with? '_spec.rb'
|
70
127
|
end
|
71
128
|
end
|
129
|
+
end
|
130
|
+
DirsHelper.add_module('serverspec-folder', ServerspecDir.new)
|
72
131
|
|
73
|
-
|
74
|
-
|
75
|
-
|
132
|
+
class FlatDir
|
133
|
+
def handles?(paths)
|
134
|
+
get_filenames(paths).empty? == false
|
135
|
+
end
|
76
136
|
|
77
|
-
def
|
78
|
-
|
137
|
+
def get_filenames(paths)
|
138
|
+
# TODO: eventually remove the metadata.rb exception here
|
139
|
+
# when we have fully phased out metadata.rb in 1.0
|
140
|
+
paths.find_all { |x| x.end_with?('.rb') && !x.include?('/') && x != 'metadata.rb' }
|
79
141
|
end
|
80
142
|
end
|
143
|
+
DirsHelper.add_module('flat-ruby-folder', FlatDir.new)
|
81
144
|
end
|
@@ -6,48 +6,33 @@ require 'inspec/targets/dir'
|
|
6
6
|
require 'inspec/targets/file'
|
7
7
|
|
8
8
|
module Inspec::Targets
|
9
|
-
class FolderHelper
|
10
|
-
def handles?(target)
|
9
|
+
class FolderHelper < DirsResolver
|
10
|
+
def self.handles?(target)
|
11
11
|
File.directory?(target)
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
attr_reader :files
|
15
|
+
|
16
|
+
def initialize(target, _opts = {})
|
17
|
+
@base_folder = target
|
15
18
|
# find all files in the folder
|
16
19
|
files = Dir[File.join(target, '**', '*')]
|
17
20
|
# remove the prefix
|
18
21
|
prefix = File.join(target, '')
|
19
|
-
files = files.map { |x| x.sub(prefix, '') }
|
20
|
-
|
21
|
-
|
22
|
-
if helper.nil?
|
23
|
-
fail "Don't know how to handle folder #{target}"
|
24
|
-
end
|
25
|
-
|
26
|
-
# get all test file contents
|
27
|
-
file_handler = Inspec::Targets.modules['file']
|
28
|
-
res = {
|
29
|
-
test: collect(helper, files, :get_filenames),
|
30
|
-
library: collect(helper, files, :get_libraries),
|
31
|
-
metadata: collect(helper, files, :get_metadata),
|
32
|
-
}.map { |as, list|
|
33
|
-
file_handler.resolve_all(list, base_folder: target, as: as)
|
34
|
-
}
|
22
|
+
@files = files.map { |x| x.sub(prefix, '') }
|
23
|
+
@file_handler = Inspec::Targets.modules['file']
|
24
|
+
end
|
35
25
|
|
36
|
-
|
37
|
-
|
26
|
+
def resolve(path, opts = {})
|
27
|
+
o = (opts || {})
|
28
|
+
o[:base_folder] = @base_folder
|
29
|
+
@file_handler.resolve(path, o)
|
38
30
|
end
|
39
31
|
|
40
32
|
def to_s
|
41
33
|
'Folder Loader'
|
42
34
|
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def collect(helper, files, getter)
|
47
|
-
return [] unless helper.respond_to? getter
|
48
|
-
helper.method(getter).call(files)
|
49
|
-
end
|
50
35
|
end
|
51
36
|
|
52
|
-
Inspec::Targets.add_module('folder', FolderHelper
|
37
|
+
Inspec::Targets.add_module('folder', FolderHelper)
|
53
38
|
end
|
data/lib/inspec/targets/tar.rb
CHANGED
@@ -8,7 +8,7 @@ require 'inspec/targets/archive'
|
|
8
8
|
|
9
9
|
module Inspec::Targets
|
10
10
|
class TarHelper < ArchiveHelper
|
11
|
-
def handles?(target)
|
11
|
+
def self.handles?(target)
|
12
12
|
File.file?(target) && target.end_with?('.tar.gz', '.tgz')
|
13
13
|
end
|
14
14
|
|
@@ -30,22 +30,20 @@ module Inspec::Targets
|
|
30
30
|
[files, rootdir]
|
31
31
|
end
|
32
32
|
|
33
|
-
def content(input,
|
34
|
-
content =
|
33
|
+
def content(input, path, rootdir = nil, opts = {})
|
34
|
+
content = nil
|
35
35
|
Gem::Package::TarReader.new(Zlib::GzipReader.open(input)) do |tar|
|
36
36
|
tar.each do |entry|
|
37
37
|
if entry.directory?
|
38
38
|
# nothing to do
|
39
39
|
elsif entry.file?
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
content.push(h)
|
48
|
-
end
|
40
|
+
next unless path == entry.full_name.gsub(rootdir, '')
|
41
|
+
content = {
|
42
|
+
# NB if some file is empty, return empty-string, not nil
|
43
|
+
content: entry.read || '',
|
44
|
+
type: opts[:as] || :test,
|
45
|
+
ref: entry.full_name,
|
46
|
+
}
|
49
47
|
elsif entry.header.typeflag == '2'
|
50
48
|
# ignore symlinks for now
|
51
49
|
end
|
@@ -59,5 +57,5 @@ module Inspec::Targets
|
|
59
57
|
end
|
60
58
|
end
|
61
59
|
|
62
|
-
Inspec::Targets.add_module('tar', TarHelper
|
60
|
+
Inspec::Targets.add_module('tar', TarHelper)
|
63
61
|
end
|
data/lib/inspec/targets/zip.rb
CHANGED
@@ -8,22 +8,22 @@ require 'inspec/targets/archive'
|
|
8
8
|
|
9
9
|
module Inspec::Targets
|
10
10
|
class ZipHelper < ArchiveHelper
|
11
|
-
def handles?(target)
|
11
|
+
def self.handles?(target)
|
12
12
|
File.file?(target) and target.end_with?('.zip')
|
13
13
|
end
|
14
14
|
|
15
|
-
def content(input,
|
16
|
-
content =
|
15
|
+
def content(input, path, rootdir = nil, opts = {})
|
16
|
+
content = nil
|
17
17
|
::Zip::InputStream.open(input) do |io|
|
18
18
|
while (entry = io.get_next_entry)
|
19
|
-
next
|
20
|
-
|
19
|
+
next unless path == entry.name.gsub(rootdir, '')
|
20
|
+
content = {
|
21
21
|
# NB if some file is empty, return empty-string, not nil
|
22
22
|
content: io.read || '',
|
23
23
|
type: opts[:as] || :test,
|
24
24
|
ref: entry.name,
|
25
25
|
}
|
26
|
-
|
26
|
+
abort
|
27
27
|
end
|
28
28
|
end
|
29
29
|
content
|
@@ -51,5 +51,5 @@ module Inspec::Targets
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
Inspec::Targets.add_module('zip', ZipHelper
|
54
|
+
Inspec::Targets.add_module('zip', ZipHelper)
|
55
55
|
end
|
data/lib/inspec/version.rb
CHANGED
data/lib/resources/iptables.rb
CHANGED
@@ -31,8 +31,8 @@ class IpTables < Inspec.resource(1)
|
|
31
31
|
"
|
32
32
|
|
33
33
|
def initialize(params = {})
|
34
|
-
@table = params[:table]
|
35
|
-
@chain = params[:chain]
|
34
|
+
@table = params[:table]
|
35
|
+
@chain = params[:chain]
|
36
36
|
|
37
37
|
# we're done if we are on linux
|
38
38
|
return if inspec.os.linux?
|
@@ -43,29 +43,26 @@ class IpTables < Inspec.resource(1)
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def has_rule?(rule = nil, _table = nil, _chain = nil)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
# for now, we expect an excact match
|
50
|
-
found = true if line.casecmp(rule) == 0
|
51
|
-
}
|
52
|
-
found
|
46
|
+
# checks if the rule is part of the ruleset
|
47
|
+
# for now, we expect an exact match
|
48
|
+
retrieve_rules.any? { |line| line.casecmp(rule) == 0 }
|
53
49
|
end
|
54
50
|
|
55
51
|
def retrieve_rules
|
56
52
|
return @iptables_cache if defined?(@iptables_cache)
|
57
53
|
|
58
54
|
# construct iptables command to read all rules
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
table_cmd = "-t #{@table}" if @table
|
56
|
+
iptables_cmd = format('iptables %s -S %s', table_cmd, @chain).strip
|
57
|
+
|
58
|
+
cmd = inspec.command(iptables_cmd)
|
62
59
|
return [] if cmd.exit_status.to_i != 0
|
63
60
|
|
64
61
|
# split rules, returns array or rules
|
65
|
-
@iptables_cache = cmd.stdout.
|
62
|
+
@iptables_cache = cmd.stdout.split("\n").map(&:strip)
|
66
63
|
end
|
67
64
|
|
68
65
|
def to_s
|
69
|
-
format('Iptables %s %s', @table
|
66
|
+
format('Iptables %s %s', @table && "table: #{@table}", @chain && "chain: #{@chain}").strip
|
70
67
|
end
|
71
68
|
end
|
data/lib/resources/service.rb
CHANGED
@@ -4,13 +4,59 @@
|
|
4
4
|
# author: Stephan Renatus
|
5
5
|
# license: All rights reserved
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
class Runlevels < Hash
|
8
|
+
attr_accessor :owner
|
9
|
+
|
10
|
+
def self.from_hash(owner, hash = {}, filter = nil)
|
11
|
+
res = Runlevels.new(owner)
|
12
|
+
filter = filter.first if filter.is_a?(Array) && filter.length <= 1
|
13
|
+
|
14
|
+
ks = case filter
|
15
|
+
when nil
|
16
|
+
hash.keys
|
17
|
+
when Regexp
|
18
|
+
hash.keys.find_all { |x| x.to_s =~ filter }
|
19
|
+
when Array
|
20
|
+
f = filter.map(&:to_s)
|
21
|
+
hash.keys.find_all { |x| f.include?(x.to_s) }
|
22
|
+
when Numeric
|
23
|
+
hash.keys.include?(filter) ? [filter] : []
|
24
|
+
else
|
25
|
+
hash.keys.find_all { |x| x == filter }
|
26
|
+
end
|
27
|
+
|
28
|
+
ks.each { |k| res[k] = hash[k] }
|
29
|
+
res
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(owner, default = false)
|
33
|
+
@owner = owner
|
34
|
+
super(default)
|
35
|
+
end
|
36
|
+
|
37
|
+
def filter(f)
|
38
|
+
Runlevels.from_hash(owner, self, f)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Check if all runlevels are enabled
|
42
|
+
#
|
43
|
+
# @return [boolean] true if all runlevels are enabled
|
44
|
+
def enabled?
|
45
|
+
values.all?
|
46
|
+
end
|
47
|
+
|
48
|
+
# Check if all runlevels are disabled
|
49
|
+
#
|
50
|
+
# @return [boolean] true if all runlevels are disabled
|
51
|
+
def disabled?
|
52
|
+
!values.any?
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
"#{owner} runlevels #{keys.join(', ')}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
14
60
|
# We detect the init system for each operating system, based on the operating
|
15
61
|
# system.
|
16
62
|
#
|
@@ -29,6 +75,10 @@ class Service < Inspec.resource(1)
|
|
29
75
|
it { should be_enabled }
|
30
76
|
it { should be_running }
|
31
77
|
end
|
78
|
+
|
79
|
+
describe service('service_name').runlevels(3, 5) do
|
80
|
+
it { should be_enabled }
|
81
|
+
end
|
32
82
|
"
|
33
83
|
|
34
84
|
attr_reader :service_ctl
|
@@ -98,7 +148,7 @@ class Service < Inspec.resource(1)
|
|
98
148
|
@cache ||= @service_mgmt.info(@service_name)
|
99
149
|
end
|
100
150
|
|
101
|
-
# verifies the service is enabled
|
151
|
+
# verifies if the service is enabled
|
102
152
|
def enabled?(_level = nil)
|
103
153
|
return false if info.nil?
|
104
154
|
info[:enabled]
|
@@ -116,6 +166,12 @@ class Service < Inspec.resource(1)
|
|
116
166
|
info[:running]
|
117
167
|
end
|
118
168
|
|
169
|
+
# get all runlevels that are available and their configuration
|
170
|
+
def runlevels(*args)
|
171
|
+
return Runlevels.new(self) if info.nil? or info[:runlevels].nil?
|
172
|
+
Runlevels.from_hash(self, info[:runlevels], args)
|
173
|
+
end
|
174
|
+
|
119
175
|
def to_s
|
120
176
|
"Service #{@service_name}"
|
121
177
|
end
|
@@ -275,6 +331,8 @@ class Upstart < ServiceManager
|
|
275
331
|
end
|
276
332
|
|
277
333
|
class SysV < ServiceManager
|
334
|
+
RUNLEVELS = { 0=>false, 1=>false, 2=>false, 3=>false, 4=>false, 5=>false, 6=>false }.freeze
|
335
|
+
|
278
336
|
def initialize(service_name, service_ctl = nil)
|
279
337
|
@service_ctl ||= 'service'
|
280
338
|
super
|
@@ -296,10 +354,15 @@ class SysV < ServiceManager
|
|
296
354
|
# on rhel via: 'chkconfig --list', is not installed by default
|
297
355
|
# bash: for i in `find /etc/rc*.d -name S*`; do basename $i | sed -r 's/^S[0-9]+//'; done | sort | uniq
|
298
356
|
enabled_services_cmd = inspec.command('find /etc/rc*.d -name S*')
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
357
|
+
service_line = %r{rc(?<runlevel>[0-6])\.d/S[^/]*?#{Regexp.escape service_name}$}
|
358
|
+
all_services = enabled_services_cmd.stdout.split("\n").map { |line|
|
359
|
+
service_line.match(line)
|
360
|
+
}.compact
|
361
|
+
enabled = !all_services.empty?
|
362
|
+
|
363
|
+
# Determine a list of runlevels which this service is activated for
|
364
|
+
runlevels = RUNLEVELS.dup
|
365
|
+
all_services.each { |x| runlevels[x[:runlevel].to_i] = true }
|
303
366
|
|
304
367
|
# check if service is really running
|
305
368
|
# service throws an exit code if the service is not installed or
|
@@ -313,6 +376,7 @@ class SysV < ServiceManager
|
|
313
376
|
installed: true,
|
314
377
|
running: running,
|
315
378
|
enabled: enabled,
|
379
|
+
runlevels: runlevels,
|
316
380
|
type: 'sysv',
|
317
381
|
}
|
318
382
|
end
|
@@ -11,6 +11,7 @@ include_recipe('os_prepare::mount')
|
|
11
11
|
include_recipe('os_prepare::service')
|
12
12
|
include_recipe('os_prepare::package')
|
13
13
|
include_recipe('os_prepare::registry_key')
|
14
|
+
include_recipe('os_prepare::iptables')
|
14
15
|
|
15
16
|
# configure repos, eg. nginx
|
16
17
|
include_recipe('os_prepare::apt')
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Stephan Renatus
|
3
|
+
|
4
|
+
case node['platform']
|
5
|
+
when 'ubuntu', 'rhel', 'centos', 'fedora'
|
6
|
+
execute 'iptables -A INPUT -i eth0 -p tcp -m tcp '\
|
7
|
+
'--dport 80 -m state --state NEW -m comment '\
|
8
|
+
'--comment "http on 80" -j ACCEPT'
|
9
|
+
execute 'iptables -N derby-cognos-web'
|
10
|
+
execute 'iptables -A INPUT -j derby-cognos-web'
|
11
|
+
execute 'iptables -A derby-cognos-web -p tcp -m tcp --dport 80 '\
|
12
|
+
'-m comment --comment "derby-cognos-web" -j ACCEPT'
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
case os[:family]
|
4
|
+
when 'ubuntu', 'fedora'
|
5
|
+
describe iptables do
|
6
|
+
it { should have_rule('-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -m comment --comment "http on 80" -j ACCEPT') }
|
7
|
+
it { should_not have_rule('-A INPUT -i eth1 -p tcp -m tcp --dport 80 -j ACCEPT') }
|
8
|
+
|
9
|
+
# single-word comments have their quotes dropped
|
10
|
+
it { should have_rule('-A derby-cognos-web -p tcp -m tcp --dport 80 -m comment --comment derby-cognos-web -j ACCEPT') }
|
11
|
+
end
|
12
|
+
when 'rhel', 'centos'
|
13
|
+
describe iptables do
|
14
|
+
it { should have_rule('-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -m comment --comment "http on 80" -j ACCEPT') }
|
15
|
+
it { should_not have_rule('-A INPUT -i eth1 -p tcp -m tcp --dport 80 -j ACCEPT') }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe iptables do
|
19
|
+
it { should have_rule('-A derby-cognos-web -p tcp -m tcp --dport 80 -m comment --comment "derby-cognos-web" -j ACCEPT') }
|
20
|
+
end if os[:release] == 6
|
21
|
+
|
22
|
+
describe iptables do
|
23
|
+
it { should have_rule('-A derby-cognos-web -p tcp -m tcp --dport 80 -m comment --comment derby-cognos-web -j ACCEPT') }
|
24
|
+
end if os[:release] == 7
|
25
|
+
end
|
@@ -3,4 +3,4 @@
|
|
3
3
|
-P OUTPUT ACCEPT
|
4
4
|
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
5
5
|
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT
|
6
|
-
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
|
6
|
+
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -m comment --comment "http like its 1990" -j ACCEPT
|
@@ -14,6 +14,11 @@ describe 'Inspec::Resources::Iptables' do
|
|
14
14
|
_(resource.has_rule?('-P OUTPUT DROP')).must_equal false
|
15
15
|
end
|
16
16
|
|
17
|
+
it 'verify iptables with comments on ubuntu' do
|
18
|
+
resource = MockLoader.new(:ubuntu1404).load_resource('iptables')
|
19
|
+
_(resource.has_rule?('-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -m comment --comment "http like its 1990" -j ACCEPT')).must_equal true
|
20
|
+
end
|
21
|
+
|
17
22
|
it 'verify iptables on windows' do
|
18
23
|
resource = MockLoader.new(:windows).load_resource('iptables')
|
19
24
|
_(resource.has_rule?('-P OUTPUT ACCEPT')).must_equal false
|
@@ -6,6 +6,7 @@ require 'helper'
|
|
6
6
|
require 'inspec/resource'
|
7
7
|
|
8
8
|
describe 'Inspec::Resources::Service' do
|
9
|
+
let(:runlevels) { {0=>false, 1=>false, 2=>true, 3=>true, 4=>true, 5=>true, 6=>false} }
|
9
10
|
|
10
11
|
# windows
|
11
12
|
it 'verify service parsing' do
|
@@ -58,7 +59,7 @@ describe 'Inspec::Resources::Service' do
|
|
58
59
|
# centos 6 with sysv
|
59
60
|
it 'verify centos 6 package parsing' do
|
60
61
|
resource = MockLoader.new(:centos6).load_resource('service', 'sshd')
|
61
|
-
srv = { name: 'sshd', description: nil, installed: true, running: true, enabled: true, type: 'sysv' }
|
62
|
+
srv = { name: 'sshd', description: nil, installed: true, running: true, enabled: true, runlevels: runlevels, type: 'sysv' }
|
62
63
|
_(resource.info).must_equal srv
|
63
64
|
_(resource.installed?).must_equal true
|
64
65
|
_(resource.enabled?).must_equal true
|
@@ -67,7 +68,7 @@ describe 'Inspec::Resources::Service' do
|
|
67
68
|
|
68
69
|
it 'verify centos 6 package parsing with default sysv_service' do
|
69
70
|
resource = MockLoader.new(:centos6).load_resource('sysv_service', 'sshd')
|
70
|
-
srv = { name: 'sshd', description: nil, installed: true, running: true, enabled: true, type: 'sysv' }
|
71
|
+
srv = { name: 'sshd', description: nil, installed: true, running: true, enabled: true, runlevels: runlevels, type: 'sysv' }
|
71
72
|
_(resource.info).must_equal srv
|
72
73
|
_(resource.installed?).must_equal true
|
73
74
|
_(resource.enabled?).must_equal true
|
@@ -125,7 +126,7 @@ describe 'Inspec::Resources::Service' do
|
|
125
126
|
# debian 7 with systemv
|
126
127
|
it 'verify debian 7 package parsing' do
|
127
128
|
resource = MockLoader.new(:debian7).load_resource('service', 'sshd')
|
128
|
-
srv = { name: 'sshd', description: nil, installed: true, running: true, enabled: true, type: 'sysv' }
|
129
|
+
srv = { name: 'sshd', description: nil, installed: true, running: true, enabled: true, runlevels: runlevels, type: 'sysv' }
|
129
130
|
_(resource.info).must_equal srv
|
130
131
|
_(resource.installed?).must_equal true
|
131
132
|
_(resource.enabled?).must_equal true
|
@@ -173,7 +174,7 @@ describe 'Inspec::Resources::Service' do
|
|
173
174
|
# wrlinux
|
174
175
|
it 'verify wrlinux package parsing' do
|
175
176
|
resource = MockLoader.new(:wrlinux).load_resource('service', 'sshd')
|
176
|
-
srv = { name: 'sshd', description: nil, installed: true, running: true, enabled: true, type: 'sysv' }
|
177
|
+
srv = { name: 'sshd', description: nil, installed: true, running: true, enabled: true, runlevels: runlevels, type: 'sysv' }
|
177
178
|
_(resource.info).must_equal srv
|
178
179
|
_(resource.installed?).must_equal true
|
179
180
|
_(resource.enabled?).must_equal true
|
@@ -187,4 +188,45 @@ describe 'Inspec::Resources::Service' do
|
|
187
188
|
_(resource.installed?).must_equal false
|
188
189
|
_(resource.info).must_equal nil
|
189
190
|
end
|
191
|
+
|
192
|
+
# runlevel detection
|
193
|
+
describe 'runlevels on centos 6 (system V)' do
|
194
|
+
let(:service) { MockLoader.new(:centos6).load_resource('service', 'sshd') }
|
195
|
+
|
196
|
+
it 'grabs all runlevels' do
|
197
|
+
service.runlevels.keys.must_equal [0, 1, 2, 3, 4, 5, 6]
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'grabs runlevels via filter nil' do
|
201
|
+
service.runlevels(nil).keys.must_equal [0, 1, 2, 3, 4, 5, 6]
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'grabs runlevels by number' do
|
205
|
+
service.runlevels(3).keys.must_equal [3]
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'grabs runlevels by multiple numbers' do
|
209
|
+
service.runlevels(3, 4, 8).keys.must_equal [3, 4]
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'grabs runlevels via regex' do
|
213
|
+
service.runlevels(/[5-9]/).keys.must_equal [5, 6]
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'checks enabled true if all services are enabled' do
|
217
|
+
service.runlevels(2, 4).enabled?.must_equal true
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'checks enabled false if some services are not enabled' do
|
221
|
+
service.runlevels(1, 4).enabled?.must_equal false
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'checks disabled true if all services are disabled' do
|
225
|
+
service.runlevels(0, 1).disabled?.must_equal true
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'checks disabled false if some services are not disabled' do
|
229
|
+
service.runlevels(0, 4).enabled?.must_equal false
|
230
|
+
end
|
231
|
+
end
|
190
232
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: r-train
|
@@ -223,6 +223,12 @@ files:
|
|
223
223
|
- lib/bundles/inspec-compliance/cli.rb
|
224
224
|
- lib/bundles/inspec-compliance/configuration.rb
|
225
225
|
- lib/bundles/inspec-compliance/target.rb
|
226
|
+
- lib/bundles/inspec-init.rb
|
227
|
+
- lib/bundles/inspec-init/cli.rb
|
228
|
+
- lib/bundles/inspec-init/templates/profile/README.md
|
229
|
+
- lib/bundles/inspec-init/templates/profile/controls/example.rb
|
230
|
+
- lib/bundles/inspec-init/templates/profile/inspec.yml
|
231
|
+
- lib/bundles/inspec-init/templates/profile/libraries/.gitkeep
|
226
232
|
- lib/bundles/inspec-supermarket/README.md
|
227
233
|
- lib/bundles/inspec-supermarket/api.rb
|
228
234
|
- lib/bundles/inspec-supermarket/cli.rb
|
@@ -339,6 +345,7 @@ files:
|
|
339
345
|
- test/integration/cookbooks/os_prepare/recipes/auditctl.rb
|
340
346
|
- test/integration/cookbooks/os_prepare/recipes/default.rb
|
341
347
|
- test/integration/cookbooks/os_prepare/recipes/file.rb
|
348
|
+
- test/integration/cookbooks/os_prepare/recipes/iptables.rb
|
342
349
|
- test/integration/cookbooks/os_prepare/recipes/json_yaml_csv_ini.rb
|
343
350
|
- test/integration/cookbooks/os_prepare/recipes/mount.rb
|
344
351
|
- test/integration/cookbooks/os_prepare/recipes/package.rb
|
@@ -356,6 +363,7 @@ files:
|
|
356
363
|
- test/integration/test/integration/default/file_spec.rb
|
357
364
|
- test/integration/test/integration/default/group_spec.rb
|
358
365
|
- test/integration/test/integration/default/ini_spec.rb
|
366
|
+
- test/integration/test/integration/default/iptables_spec.rb
|
359
367
|
- test/integration/test/integration/default/json_spec.rb
|
360
368
|
- test/integration/test/integration/default/kernel_module_spec.rb
|
361
369
|
- test/integration/test/integration/default/kernel_parameter_spec.rb
|
@@ -570,6 +578,7 @@ test_files:
|
|
570
578
|
- test/integration/cookbooks/os_prepare/recipes/auditctl.rb
|
571
579
|
- test/integration/cookbooks/os_prepare/recipes/default.rb
|
572
580
|
- test/integration/cookbooks/os_prepare/recipes/file.rb
|
581
|
+
- test/integration/cookbooks/os_prepare/recipes/iptables.rb
|
573
582
|
- test/integration/cookbooks/os_prepare/recipes/json_yaml_csv_ini.rb
|
574
583
|
- test/integration/cookbooks/os_prepare/recipes/mount.rb
|
575
584
|
- test/integration/cookbooks/os_prepare/recipes/package.rb
|
@@ -587,6 +596,7 @@ test_files:
|
|
587
596
|
- test/integration/test/integration/default/file_spec.rb
|
588
597
|
- test/integration/test/integration/default/group_spec.rb
|
589
598
|
- test/integration/test/integration/default/ini_spec.rb
|
599
|
+
- test/integration/test/integration/default/iptables_spec.rb
|
590
600
|
- test/integration/test/integration/default/json_spec.rb
|
591
601
|
- test/integration/test/integration/default/kernel_module_spec.rb
|
592
602
|
- test/integration/test/integration/default/kernel_parameter_spec.rb
|