inspec 0.14.8 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -2
- data/bin/inspec +3 -4
- data/examples/inheritance/README.md +19 -0
- data/examples/inheritance/controls/example.rb +11 -0
- data/examples/inheritance/inspec.yml +10 -0
- data/lib/bundles/inspec-compliance/cli.rb +1 -4
- data/lib/bundles/inspec-supermarket/cli.rb +1 -4
- data/lib/inspec/dsl.rb +48 -55
- data/lib/inspec/profile.rb +6 -2
- data/lib/inspec/profile_context.rb +21 -8
- data/lib/inspec/runner.rb +17 -12
- data/lib/inspec/runner_rspec.rb +1 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/apache.rb +20 -18
- data/lib/resources/apache_conf.rb +92 -90
- data/lib/resources/apt.rb +92 -90
- data/lib/resources/audit_policy.rb +35 -33
- data/lib/resources/auditd_conf.rb +41 -39
- data/lib/resources/auditd_rules.rb +155 -153
- data/lib/resources/bond.rb +1 -1
- data/lib/resources/bridge.rb +97 -95
- data/lib/resources/command.rb +47 -45
- data/lib/resources/csv.rb +23 -21
- data/lib/resources/directory.rb +1 -1
- data/lib/resources/etc_group.rb +116 -114
- data/lib/resources/file.rb +1 -1
- data/lib/resources/gem.rb +39 -37
- data/lib/resources/group.rb +100 -98
- data/lib/resources/host.rb +103 -101
- data/lib/resources/inetd_conf.rb +42 -40
- data/lib/resources/ini.rb +15 -13
- data/lib/resources/interface.rb +106 -104
- data/lib/resources/iptables.rb +36 -34
- data/lib/resources/json.rb +64 -62
- data/lib/resources/kernel_module.rb +30 -28
- data/lib/resources/kernel_parameter.rb +44 -42
- data/lib/resources/limits_conf.rb +41 -39
- data/lib/resources/login_def.rb +38 -36
- data/lib/resources/mount.rb +43 -41
- data/lib/resources/mysql.rb +67 -65
- data/lib/resources/mysql_conf.rb +89 -87
- data/lib/resources/mysql_session.rb +46 -44
- data/lib/resources/npm.rb +35 -33
- data/lib/resources/ntp_conf.rb +44 -42
- data/lib/resources/oneget.rb +46 -44
- data/lib/resources/os.rb +22 -20
- data/lib/resources/os_env.rb +47 -45
- data/lib/resources/package.rb +213 -211
- data/lib/resources/parse_config.rb +59 -57
- data/lib/resources/passwd.rb +89 -87
- data/lib/resources/pip.rb +60 -58
- data/lib/resources/port.rb +352 -350
- data/lib/resources/postgres.rb +26 -24
- data/lib/resources/postgres_conf.rb +66 -64
- data/lib/resources/postgres_session.rb +47 -45
- data/lib/resources/processes.rb +56 -54
- data/lib/resources/registry_key.rb +150 -148
- data/lib/resources/script.rb +30 -28
- data/lib/resources/security_policy.rb +56 -54
- data/lib/resources/service.rb +638 -636
- data/lib/resources/shadow.rb +98 -96
- data/lib/resources/ssh_conf.rb +58 -56
- data/lib/resources/user.rb +363 -361
- data/lib/resources/windows_feature.rb +46 -44
- data/lib/resources/xinetd.rb +111 -109
- data/lib/resources/yaml.rb +16 -14
- data/lib/resources/yum.rb +107 -105
- data/lib/utils/base_cli.rb +18 -0
- data/test/helper.rb +2 -2
- data/test/unit/profile_context_test.rb +1 -1
- data/test/unit/resources/file_test.rb +1 -1
- data/test/unit/resources/mount_test.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ca71e169ffd037a7a61f99fc09188424a137168
|
4
|
+
data.tar.gz: 1aa83936f8b464a2044a7fae20cb14ddce1bdb87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 774c8531d3bfdcab1c0a0587f670c09ab39099e89ff07a79e68c37bb3798e1a1a75e0b613c80a7bc7f8fb492c797ec26b04a12298a0493ddfd0d7784059cfb99
|
7
|
+
data.tar.gz: 4335e3fa250d9b6e3b54e25c82289fb3f232452ced7ad0d1a781349b2ae415d8b9533824c4ffda2f53340a96da0cea3720dd630637b59a6286511021672c3945
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,29 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [0.
|
4
|
-
[Full Changelog](https://github.com/chef/inspec/compare/v0.14.
|
3
|
+
## [0.15.0](https://github.com/chef/inspec/tree/0.15.0) (2016-03-09)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.14.8...0.15.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- add color output + make it the default [\#523](https://github.com/chef/inspec/pull/523) ([arlimus](https://github.com/arlimus))
|
9
|
+
- select controls to execute [\#522](https://github.com/chef/inspec/pull/522) ([arlimus](https://github.com/arlimus))
|
10
|
+
|
11
|
+
**Fixed bugs:**
|
12
|
+
|
13
|
+
- Rename internal File and OS resource classes [\#527](https://github.com/chef/inspec/pull/527) ([arlimus](https://github.com/arlimus))
|
14
|
+
- Placing all resources in the Inspec::Resources namespace [\#526](https://github.com/chef/inspec/pull/526) ([adamleff](https://github.com/adamleff))
|
15
|
+
- bugfix: inheritance of local profiles [\#524](https://github.com/chef/inspec/pull/524) ([arlimus](https://github.com/arlimus))
|
16
|
+
|
17
|
+
**Closed issues:**
|
18
|
+
|
19
|
+
- Colo\[u\]r those dots and Fs! [\#518](https://github.com/chef/inspec/issues/518)
|
20
|
+
|
21
|
+
**Merged pull requests:**
|
22
|
+
|
23
|
+
- 0.14.9 [\#525](https://github.com/chef/inspec/pull/525) ([arlimus](https://github.com/arlimus))
|
24
|
+
|
25
|
+
## [v0.14.8](https://github.com/chef/inspec/tree/v0.14.8) (2016-03-04)
|
26
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.14.7...v0.14.8)
|
5
27
|
|
6
28
|
**Closed issues:**
|
7
29
|
|
@@ -9,6 +31,7 @@
|
|
9
31
|
|
10
32
|
**Merged pull requests:**
|
11
33
|
|
34
|
+
- 0.14.8 [\#520](https://github.com/chef/inspec/pull/520) ([arlimus](https://github.com/arlimus))
|
12
35
|
- expose control impacts in json [\#519](https://github.com/chef/inspec/pull/519) ([arlimus](https://github.com/arlimus))
|
13
36
|
|
14
37
|
## [v0.14.7](https://github.com/chef/inspec/tree/v0.14.7) (2016-03-01)
|
data/bin/inspec
CHANGED
@@ -20,6 +20,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
20
20
|
desc: 'Attach a profile ID to all test results'
|
21
21
|
option :output, aliases: :o, type: :string,
|
22
22
|
desc: 'Save the created profile to a path'
|
23
|
+
profile_options
|
23
24
|
def json(target)
|
24
25
|
diagnose
|
25
26
|
o = opts.dup
|
@@ -42,6 +43,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
42
43
|
|
43
44
|
desc 'check PATH', 'verify all tests at the specified PATH'
|
44
45
|
option :format, type: :string
|
46
|
+
profile_options
|
45
47
|
def check(path) # rubocop:disable Metrics/AbcSize
|
46
48
|
diagnose
|
47
49
|
o = opts.dup
|
@@ -101,10 +103,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
101
103
|
end
|
102
104
|
|
103
105
|
desc 'exec PATHS', 'run all test files at the specified PATH.'
|
104
|
-
|
105
|
-
desc: 'Attach a profile ID to all test results'
|
106
|
-
target_options
|
107
|
-
option :format, type: :string
|
106
|
+
exec_options
|
108
107
|
def exec(*targets)
|
109
108
|
diagnose
|
110
109
|
run_tests(targets, opts)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Example InSpec Profile
|
2
|
+
|
3
|
+
This example shows the use of InSpec [profile](../../docs/profiles.rst) inheritance.
|
4
|
+
|
5
|
+
## Verify a profile
|
6
|
+
|
7
|
+
InSpec ships with built-in features to verify a profile structure.
|
8
|
+
|
9
|
+
```bash
|
10
|
+
$ inspec check examples/inheritance --profiles-path examples
|
11
|
+
```
|
12
|
+
|
13
|
+
## Execute a profile
|
14
|
+
|
15
|
+
To run a profile on a local machine use `inspec exec /path/to/profile`.
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ inspec exec examples/inheritance --profiles-path examples
|
19
|
+
```
|
@@ -0,0 +1,10 @@
|
|
1
|
+
name: inheritance
|
2
|
+
title: InSpec example inheritance
|
3
|
+
maintainer: Chef Software, Inc.
|
4
|
+
copyright: Chef Software, Inc.
|
5
|
+
copyright_email: support@chef.io
|
6
|
+
license: Apache 2 license
|
7
|
+
summary: Demonstrates the use of InSpec profile inheritance
|
8
|
+
version: 1.0.0
|
9
|
+
supports:
|
10
|
+
- os-family: linux
|
@@ -39,10 +39,7 @@ module Compliance
|
|
39
39
|
end
|
40
40
|
|
41
41
|
desc 'exec PROFILE', 'executes a Chef Compliance profile'
|
42
|
-
|
43
|
-
desc: 'Attach a profile ID to all test results'
|
44
|
-
target_options
|
45
|
-
option :format, type: :string
|
42
|
+
exec_options
|
46
43
|
def exec(*tests)
|
47
44
|
# iterate over tests and add compliance scheme
|
48
45
|
tests = tests.map { |t| 'compliance://' + t }
|
@@ -18,10 +18,7 @@ module Supermarket
|
|
18
18
|
end
|
19
19
|
|
20
20
|
desc 'exec PROFILE', 'execute a Supermarket profile'
|
21
|
-
|
22
|
-
desc: 'Attach a profile ID to all test results'
|
23
|
-
target_options
|
24
|
-
option :format, type: :string
|
21
|
+
exec_options
|
25
22
|
def exec(*tests)
|
26
23
|
# iterate over tests and add compliance scheme
|
27
24
|
tests = tests.map { |t| 'supermarket://' + t }
|
data/lib/inspec/dsl.rb
CHANGED
@@ -6,11 +6,13 @@
|
|
6
6
|
|
7
7
|
module Inspec::DSL
|
8
8
|
def require_controls(id, &block)
|
9
|
-
|
9
|
+
opts = { profile_id: id, include_all: false, backend: @backend, conf: @conf }
|
10
|
+
::Inspec::DSL.load_spec_files_for_profile(self, opts, &block)
|
10
11
|
end
|
11
12
|
|
12
13
|
def include_controls(id, &block)
|
13
|
-
|
14
|
+
opts = { profile_id: id, include_all: true, backend: @backend, conf: @conf }
|
15
|
+
::Inspec::DSL.load_spec_files_for_profile(self, opts, &block)
|
14
16
|
end
|
15
17
|
|
16
18
|
alias require_rules require_controls
|
@@ -60,72 +62,63 @@ module Inspec::DSL
|
|
60
62
|
}
|
61
63
|
end
|
62
64
|
|
63
|
-
def self.
|
64
|
-
|
65
|
-
|
65
|
+
def self.load_spec_files_for_profile(bind_context, opts, &block)
|
66
|
+
# get all spec files
|
67
|
+
target = get_reference_profile(opts[:profile_id], opts[:conf])
|
68
|
+
profile = Inspec::Profile.for_target(target, opts)
|
69
|
+
context = load_profile_context(opts[:profile_id], profile, opts)
|
66
70
|
|
67
|
-
|
68
|
-
|
69
|
-
|
71
|
+
# if we don't want all the rules, then just make 1 pass to get all rule_IDs
|
72
|
+
# that we want to keep from the original
|
73
|
+
filter_included_controls(context, opts, &block) if !opts[:include_all]
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
files = get_spec_files_for_profile profile_id
|
74
|
-
# load all rules from spec files
|
75
|
-
rule_registry = {}
|
76
|
-
# TODO: handling of only_ifs
|
77
|
-
only_ifs = []
|
78
|
-
files.each do |file|
|
79
|
-
load_spec_file_for_profile(profile_id, file, rule_registry, only_ifs)
|
80
|
-
end
|
75
|
+
# interpret the block and skip/modify as required
|
76
|
+
context.load(block) if block_given?
|
81
77
|
|
82
|
-
#
|
83
|
-
|
84
|
-
|
85
|
-
ctx = Inspec::ProfileContext.new(profile_id, block_registry, only_ifs)
|
86
|
-
ctx.instance_eval(&block)
|
78
|
+
# finally register all combined rules
|
79
|
+
context.rules.values.each do |control|
|
80
|
+
bind_context.register_control(control)
|
87
81
|
end
|
82
|
+
end
|
88
83
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
84
|
+
def self.filter_included_controls(context, opts, &block)
|
85
|
+
mock = Inspec::Backend.create({ backend: 'mock' })
|
86
|
+
include_ctx = Inspec::ProfileContext.new(opts[:profile_id], mock, opts[:conf])
|
87
|
+
include_ctx.load(block) if block_given?
|
88
|
+
# remove all rules that were not registered
|
89
|
+
context.rules.keys.each do |id|
|
90
|
+
unless include_ctx.rules[id]
|
91
|
+
context.rules[id] = nil
|
92
|
+
end
|
94
93
|
end
|
94
|
+
end
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
elsif r.nil?
|
103
|
-
rule_registry.delete(id)
|
104
|
-
else
|
105
|
-
merge_rules(org, r)
|
106
|
-
end
|
96
|
+
def self.get_reference_profile(id, opts)
|
97
|
+
profiles_path = opts['profiles_path'] ||
|
98
|
+
fail('You must supply a --profiles-path to inherit from other profiles.')
|
99
|
+
abs_path = File.expand_path(profiles_path.to_s)
|
100
|
+
unless File.directory? abs_path
|
101
|
+
fail("Cannot find profiles path #{abs_path}")
|
107
102
|
end
|
108
103
|
|
109
|
-
|
110
|
-
|
111
|
-
|
104
|
+
id_path = File.join(abs_path, id)
|
105
|
+
unless File.directory? id_path
|
106
|
+
fail("Cannot find referenced profile #{id} in #{id_path}")
|
112
107
|
end
|
108
|
+
|
109
|
+
id_path
|
113
110
|
end
|
114
111
|
|
115
|
-
def self.
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
if File.directory? libdir and !$LOAD_PATH.include?(libdir)
|
124
|
-
$LOAD_PATH.unshift(libdir)
|
125
|
-
end
|
126
|
-
files = Dir[File.join(path, 'spec', '*_spec.rb')]
|
112
|
+
def self.load_profile_context(id, profile, opts)
|
113
|
+
ctx = Inspec::ProfileContext.new(id, opts[:backend], opts[:conf])
|
114
|
+
profile.libraries.each do |path, content|
|
115
|
+
ctx.load(content.to_s, path, 1)
|
116
|
+
ctx.reload_dsl
|
117
|
+
end
|
118
|
+
profile.tests.each do |path, content|
|
119
|
+
ctx.load(content.to_s, path, 1)
|
127
120
|
end
|
128
|
-
|
121
|
+
ctx
|
129
122
|
end
|
130
123
|
end
|
131
124
|
|
data/lib/inspec/profile.rb
CHANGED
@@ -13,7 +13,7 @@ module Inspec
|
|
13
13
|
extend Forwardable
|
14
14
|
attr_reader :path
|
15
15
|
|
16
|
-
def self.
|
16
|
+
def self.resolve_target(target, opts)
|
17
17
|
# Fetchers retrieve file contents
|
18
18
|
opts[:target] = target
|
19
19
|
fetcher = Inspec::Fetcher.resolve(target)
|
@@ -27,7 +27,11 @@ module Inspec
|
|
27
27
|
fail("Don't understand inspec profile in #{target.inspect}, it "\
|
28
28
|
"doesn't look like a supported profile structure.")
|
29
29
|
end
|
30
|
-
|
30
|
+
reader
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.for_target(target, opts)
|
34
|
+
new(resolve_target(target, opts), opts)
|
31
35
|
end
|
32
36
|
|
33
37
|
attr_reader :source_reader
|
@@ -7,18 +7,18 @@ require 'inspec/dsl'
|
|
7
7
|
require 'securerandom'
|
8
8
|
|
9
9
|
module Inspec
|
10
|
-
class ProfileContext
|
11
|
-
attr_reader :rules
|
12
|
-
def initialize(profile_id, backend,
|
10
|
+
class ProfileContext # rubocop:disable Metrics/ClassLength
|
11
|
+
attr_reader :rules
|
12
|
+
def initialize(profile_id, backend, conf)
|
13
13
|
if backend.nil?
|
14
14
|
fail 'ProfileContext is initiated with a backend == nil. ' \
|
15
15
|
'This is a backend error which must be fixed upstream.'
|
16
16
|
end
|
17
17
|
|
18
18
|
@profile_id = profile_id
|
19
|
-
@rules = profile_registry
|
20
|
-
@only_ifs = only_ifs
|
21
19
|
@backend = backend
|
20
|
+
@conf = conf.dup
|
21
|
+
@rules = {}
|
22
22
|
|
23
23
|
reload_dsl
|
24
24
|
end
|
@@ -26,12 +26,16 @@ module Inspec
|
|
26
26
|
def reload_dsl
|
27
27
|
resources_dsl = Inspec::Resource.create_dsl(@backend)
|
28
28
|
ctx = create_context(resources_dsl, rule_context(resources_dsl))
|
29
|
-
@profile_context = ctx.new
|
29
|
+
@profile_context = ctx.new(@backend, @conf)
|
30
30
|
end
|
31
31
|
|
32
32
|
def load(content, source = nil, line = nil)
|
33
33
|
@current_load = { file: source }
|
34
|
-
|
34
|
+
if content.is_a? Proc
|
35
|
+
@profile_context.instance_eval(&content)
|
36
|
+
else
|
37
|
+
@profile_context.instance_eval(content, source || 'unknown', line || 1)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
|
37
41
|
def unregister_rule(id)
|
@@ -93,6 +97,11 @@ module Inspec
|
|
93
97
|
include Inspec::DSL
|
94
98
|
include resources_dsl
|
95
99
|
|
100
|
+
def initialize(backend, conf) # rubocop:disable Lint/NestedMethodDefinition, Lint/DuplicateMethods
|
101
|
+
@backend = backend
|
102
|
+
@conf = conf
|
103
|
+
end
|
104
|
+
|
96
105
|
define_method :title do |arg|
|
97
106
|
profile_context_owner.set_header(:title, arg)
|
98
107
|
end
|
@@ -116,6 +125,10 @@ module Inspec
|
|
116
125
|
|
117
126
|
alias_method :rule, :control
|
118
127
|
|
128
|
+
define_method :register_control do |control|
|
129
|
+
profile_context_owner.register_rule(control) unless control.nil?
|
130
|
+
end
|
131
|
+
|
119
132
|
define_method :describe do |*args, &block|
|
120
133
|
loc = block_location(block, caller[0])
|
121
134
|
id = "(generated from #{loc} #{SecureRandom.hex})"
|
@@ -133,7 +146,7 @@ module Inspec
|
|
133
146
|
nil
|
134
147
|
end
|
135
148
|
|
136
|
-
|
149
|
+
define_method :skip_control do |id|
|
137
150
|
profile_context_owner.unregister_rule(id)
|
138
151
|
end
|
139
152
|
|
data/lib/inspec/runner.rb
CHANGED
@@ -46,6 +46,12 @@ module Inspec
|
|
46
46
|
@backend = Inspec::Backend.create(@conf)
|
47
47
|
end
|
48
48
|
|
49
|
+
def add_target(target, options = {})
|
50
|
+
profile = Inspec::Profile.for_target(target, options)
|
51
|
+
fail "Could not resolve #{target} to valid input." if profile.nil?
|
52
|
+
add_profile(profile, options)
|
53
|
+
end
|
54
|
+
|
49
55
|
def add_profile(profile, options = {})
|
50
56
|
return unless options[:ignore_supports] ||
|
51
57
|
profile.metadata.supports_transport?(@backend)
|
@@ -57,26 +63,20 @@ module Inspec
|
|
57
63
|
profile.tests.each do |ref, content|
|
58
64
|
r = profile.source_reader.target.abs_path(ref)
|
59
65
|
test = { ref: r, content: content }
|
60
|
-
add_content(test, libs)
|
66
|
+
add_content(test, libs, options)
|
61
67
|
end
|
62
68
|
end
|
63
69
|
|
64
|
-
def
|
65
|
-
|
66
|
-
fail "Could not resolve #{target} to valid input." if profile.nil?
|
67
|
-
add_profile(profile)
|
68
|
-
end
|
69
|
-
|
70
|
-
def create_context
|
71
|
-
Inspec::ProfileContext.new(@profile_id, @backend)
|
70
|
+
def create_context(options = {})
|
71
|
+
Inspec::ProfileContext.new(@profile_id, @backend, @conf.merge(options))
|
72
72
|
end
|
73
73
|
|
74
|
-
def add_content(test, libs)
|
74
|
+
def add_content(test, libs, options = {})
|
75
75
|
content = test[:content]
|
76
76
|
return if content.nil? || content.empty?
|
77
77
|
|
78
78
|
# load all libraries
|
79
|
-
ctx = create_context
|
79
|
+
ctx = create_context(options)
|
80
80
|
libs.each do |lib|
|
81
81
|
ctx.load(lib[:content].to_s, lib[:ref], lib[:line] || 1)
|
82
82
|
ctx.reload_dsl
|
@@ -86,7 +86,7 @@ module Inspec
|
|
86
86
|
ctx.load(content, test[:ref], test[:line] || 1)
|
87
87
|
|
88
88
|
# process the resulting rules
|
89
|
-
ctx.rules.each do |rule_id, rule|
|
89
|
+
filter_controls(ctx.rules, options[:controls]).each do |rule_id, rule|
|
90
90
|
register_rule(rule_id, rule)
|
91
91
|
end
|
92
92
|
end
|
@@ -96,6 +96,11 @@ module Inspec
|
|
96
96
|
|
97
97
|
private
|
98
98
|
|
99
|
+
def filter_controls(controls_map, include_list)
|
100
|
+
return controls_map if include_list.nil? || include_list.empty?
|
101
|
+
controls_map.select { |k, _| include_list.include?(k) }
|
102
|
+
end
|
103
|
+
|
99
104
|
def block_source_info(block)
|
100
105
|
return {} if block.nil? || !block.respond_to?(:source_location)
|
101
106
|
opts = {}
|