inspec 0.9.11 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +45 -2
- data/bin/inspec +53 -86
- data/examples/kitchen-ansible/.kitchen/default-ubuntu-1404.yml +2 -2
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1404/.vagrant/machines/default/virtualbox/action_set_name +1 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1404/.vagrant/machines/default/virtualbox/id +1 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1404/.vagrant/machines/default/virtualbox/index_uuid +1 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1404/.vagrant/machines/default/virtualbox/private_key +25 -25
- data/examples/kitchen-ansible/.kitchen/logs/default-centos-71.log +0 -4
- data/examples/kitchen-ansible/.kitchen/logs/default-ubuntu-1204.log +0 -4
- data/examples/kitchen-ansible/.kitchen/logs/default-ubuntu-1404.log +395 -4
- data/examples/kitchen-ansible/.kitchen/logs/kitchen.log +3 -8
- data/examples/kitchen-ansible/Gemfile.lock +29 -25
- data/examples/kitchen-ansible/test/.DS_Store +0 -0
- data/examples/kitchen-ansible/test/integration/.DS_Store +0 -0
- data/examples/kitchen-azure/.kitchen.yml +30 -0
- data/examples/kitchen-azure/.kitchen/default-debian-80-20151022-x86-64.yml +1 -0
- data/examples/kitchen-azure/.kitchen/default-ubuntu-1204.yml +9 -0
- data/examples/kitchen-azure/.kitchen/logs/default-debian-80-20151022-x86-64.log +59 -0
- data/examples/kitchen-azure/.kitchen/logs/default-ubuntu-1204.log +27 -0
- data/{lib/resources/certificate.rb → examples/kitchen-azure/.kitchen/logs/default-windows2012-r2.log} +0 -0
- data/examples/kitchen-azure/.kitchen/logs/kitchen.log +29 -0
- data/examples/kitchen-azure/Berksfile +3 -0
- data/examples/kitchen-azure/Gemfile +20 -0
- data/examples/kitchen-azure/Gemfile.lock +273 -0
- data/examples/kitchen-azure/README.md +14 -0
- data/{lib/resources/private_key.rb → examples/kitchen-azure/credentials.sh} +0 -0
- data/examples/kitchen-azure/metadata.rb +7 -0
- data/examples/kitchen-azure/recipes/default.rb +6 -0
- data/examples/kitchen-azure/recipes/nginx.rb +30 -0
- data/examples/kitchen-azure/test/integration/default/web_spec.rb +28 -0
- data/examples/kitchen-chef/.kitchen/default-ubuntu-1404.yml +1 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1404/.vagrant/machines/default/virtualbox/action_set_name +1 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1404/.vagrant/machines/default/virtualbox/id +1 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1404/.vagrant/machines/default/virtualbox/index_uuid +1 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1404/.vagrant/machines/default/virtualbox/private_key +25 -25
- data/examples/kitchen-chef/.kitchen/logs/default-centos-71.log +0 -4
- data/examples/kitchen-chef/.kitchen/logs/default-ubuntu-1204.log +0 -4
- data/examples/kitchen-chef/.kitchen/logs/default-ubuntu-1404.log +3 -4
- data/examples/kitchen-chef/.kitchen/logs/kitchen.log +3 -8
- data/examples/kitchen-chef/Gemfile.lock +27 -24
- data/examples/kitchen-chef/test/integration/.DS_Store +0 -0
- data/examples/{kitchen-chef/.kitchen/default-ubuntu-1204.yml → kitchen-puppet/.kitchen/default-ubuntu-1404.yml} +1 -1
- data/examples/kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404/.vagrant/machines/default/virtualbox/action_set_name +1 -0
- data/examples/{kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71 → kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404}/.vagrant/machines/default/virtualbox/creator_uid +0 -0
- data/examples/kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404/.vagrant/machines/default/virtualbox/id +1 -0
- data/examples/kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404/.vagrant/machines/default/virtualbox/index_uuid +1 -0
- data/examples/kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404/.vagrant/machines/default/virtualbox/private_key +27 -0
- data/examples/{kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71 → kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404}/.vagrant/machines/default/virtualbox/synced_folders +0 -0
- data/examples/{kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71 → kitchen-puppet/.kitchen/kitchen-vagrant/kitchen-kitchen-puppet-default-ubuntu-1404}/Vagrantfile +3 -3
- data/examples/kitchen-puppet/.kitchen/logs/default-centos-71.log +0 -5
- data/examples/kitchen-puppet/.kitchen/logs/default-ubuntu-1204.log +0 -5
- data/examples/kitchen-puppet/.kitchen/logs/default-ubuntu-1404.log +305 -5
- data/examples/kitchen-puppet/.kitchen/logs/kitchen.log +6 -5
- data/examples/kitchen-puppet/.librarian/puppet/config +1 -1
- data/examples/kitchen-puppet/Gemfile.lock +22 -21
- data/examples/kitchen-puppet/test/integration/.DS_Store +0 -0
- data/examples/kitchen-puppet/test/integration/default/.DS_Store +0 -0
- data/examples/profile/controls/example.rb +7 -1
- data/lib/bundles/README.md +3 -0
- data/lib/bundles/inspec-compliance.rb +14 -0
- data/lib/bundles/inspec-compliance/README.md +20 -0
- data/lib/bundles/inspec-compliance/TODO.md +4 -0
- data/lib/bundles/inspec-compliance/api.rb +134 -0
- data/lib/bundles/inspec-compliance/cli.rb +146 -0
- data/lib/bundles/inspec-compliance/configuration.rb +52 -0
- data/lib/bundles/inspec-compliance/target.rb +61 -0
- data/lib/bundles/inspec-supermarket.rb +14 -0
- data/lib/bundles/inspec-supermarket/README.md +31 -0
- data/lib/bundles/inspec-supermarket/TODO.md +5 -0
- data/lib/bundles/inspec-supermarket/api.rb +58 -0
- data/lib/bundles/inspec-supermarket/cache.rb +30 -0
- data/lib/bundles/inspec-supermarket/cli.rb +54 -0
- data/lib/bundles/inspec-supermarket/target.rb +49 -0
- data/lib/inspec.rb +9 -2
- data/lib/inspec/metadata.rb +21 -7
- data/lib/inspec/plugins.rb +41 -0
- data/lib/inspec/plugins/cli.rb +24 -0
- data/lib/inspec/profile.rb +90 -61
- data/lib/inspec/rule.rb +9 -0
- data/lib/inspec/runner.rb +7 -3
- data/lib/inspec/runner_rspec.rb +19 -0
- data/lib/inspec/targets/archive.rb +14 -10
- data/lib/inspec/targets/tar.rb +3 -2
- data/lib/inspec/targets/url.rb +5 -4
- data/lib/inspec/targets/zip.rb +3 -2
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/file.rb +7 -21
- data/lib/resources/os.rb +1 -1
- data/lib/resources/service.rb +15 -3
- data/lib/utils/base_cli.rb +131 -0
- data/lib/utils/find_files.rb +1 -1
- data/lib/utils/json_log.rb +17 -0
- data/test/helper.rb +39 -25
- data/test/integration/.kitchen.chef.yml +1 -1
- data/test/integration/.kitchen.ec2.yml +2 -0
- data/test/integration/.kitchen/default-aws-linux.yml +4 -0
- data/test/integration/.kitchen/default-centos-7.yml +4 -0
- data/test/integration/.kitchen/default-chef-solaris-113.yml +6 -0
- data/test/integration/.kitchen/default-chef-windows-server-2008r2-standard.yml +1 -1
- data/test/integration/.kitchen/default-debian-8.yml +4 -0
- data/test/integration/.kitchen/default-fedora-22.yml +4 -0
- data/test/integration/.kitchen/default-redhat-65.yml +4 -0
- data/test/integration/.kitchen/default-redhat-71.yml +4 -0
- data/test/integration/.kitchen/default-suse-11sp3.yml +4 -0
- data/test/integration/.kitchen/default-suse-12.yml +4 -0
- data/test/integration/.kitchen/default-suse-hi11sp3.yml +4 -0
- data/test/integration/.kitchen/default-ubuntu-1204.yml +4 -0
- data/test/integration/.kitchen/default-ubuntu-1404.yml +4 -0
- data/test/integration/.kitchen/default-ubuntu-1510.yml +4 -0
- data/test/integration/.kitchen/default-windows-2012r2.yml +6 -0
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113/.vagrant/machines/default/virtualbox/action_set_name +1 -0
- data/{examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204 → test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113}/.vagrant/machines/default/virtualbox/creator_uid +0 -0
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113/.vagrant/machines/default/virtualbox/id +1 -0
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113/.vagrant/machines/default/virtualbox/index_uuid +1 -0
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113/.vagrant/machines/default/virtualbox/private_key +27 -0
- data/{examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204 → test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-solaris-113}/.vagrant/machines/default/virtualbox/synced_folders +0 -0
- data/test/integration/.kitchen/kitchen-vagrant/{kitchen-integration-default-chef-windows-server-2012r2-standard → kitchen-integration-default-chef-solaris-113}/Vagrantfile +2 -2
- data/test/integration/.kitchen/logs/default-aws-linux.log +0 -3
- data/test/integration/.kitchen/logs/default-centos-7.log +0 -3
- data/test/integration/.kitchen/logs/default-chef-solaris-113.log +0 -0
- data/test/integration/.kitchen/logs/default-chef-windows-server-2008r2-standard.log +43 -0
- data/test/integration/.kitchen/logs/default-chris-rock-omnios-r151014.log +41 -23
- data/test/integration/.kitchen/logs/default-debian-8.log +0 -3
- data/test/integration/.kitchen/logs/default-fedora-22.log +0 -3
- data/test/integration/.kitchen/logs/default-redhat-65.log +0 -3
- data/test/integration/.kitchen/logs/default-redhat-71.log +0 -3
- data/test/integration/.kitchen/logs/default-suse-11sp3.log +0 -3
- data/test/integration/.kitchen/logs/default-suse-12.log +0 -3
- data/test/integration/.kitchen/logs/default-suse-hi11sp3.log +37 -0
- data/test/integration/.kitchen/logs/default-ubuntu-1204.log +23 -3
- data/test/integration/.kitchen/logs/default-ubuntu-1404.log +0 -3
- data/test/integration/.kitchen/logs/default-ubuntu-1510.log +0 -3
- data/test/integration/.kitchen/logs/default-windows-2012r2.log +0 -2
- data/test/integration/.kitchen/logs/kitchen.log +3 -14
- data/test/integration/cookbooks/os_prepare/recipes/_upstart_service_centos.rb +21 -0
- data/test/integration/cookbooks/os_prepare/recipes/apache.rb +14 -0
- data/test/integration/cookbooks/os_prepare/recipes/service.rb +1 -0
- data/test/integration/test/integration/default/service_spec.rb +24 -0
- data/test/solaris_test.rb +70 -0
- data/test/unit/mock/cmd/initctl--version +5 -0
- data/test/unit/plugin_test.rb +46 -0
- data/test/unit/profile_test.rb +136 -21
- data/test/unit/resources/file_test.rb +13 -25
- metadata +105 -51
- data/examples/kitchen-ansible/.kitchen/default-centos-71.yml +0 -6
- data/examples/kitchen-ansible/.kitchen/default-ubuntu-1204.yml +0 -6
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71/.vagrant/machines/default/virtualbox/id +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-centos-71/.vagrant/machines/default/virtualbox/private_key +0 -27
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/.vagrant/machines/default/virtualbox/id +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/.vagrant/machines/default/virtualbox/private_key +0 -27
- data/examples/kitchen-ansible/.kitchen/kitchen-vagrant/kitchen-kitchen-ansible-default-ubuntu-1204/Vagrantfile +0 -9
- data/examples/kitchen-chef/.kitchen/default-centos-71.yml +0 -6
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/creator_uid +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/id +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/private_key +0 -27
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/.vagrant/machines/default/virtualbox/synced_folders +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-centos-71/Vagrantfile +0 -9
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/creator_uid +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/id +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/private_key +0 -27
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/.vagrant/machines/default/virtualbox/synced_folders +0 -1
- data/examples/kitchen-chef/.kitchen/kitchen-vagrant/kitchen-kitchen-chef-default-ubuntu-1204/Vagrantfile +0 -9
- data/test/integration/.kitchen/default-chef-windows-server-2012r2-standard.yml +0 -7
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/action_set_name +0 -1
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/creator_uid +0 -1
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/id +0 -1
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/index_uuid +0 -1
- data/test/integration/.kitchen/kitchen-vagrant/kitchen-integration-default-chef-windows-server-2012r2-standard/.vagrant/machines/default/virtualbox/synced_folders +0 -1
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Christoph Hartmann
|
3
|
+
# author: Dominik Richter
|
4
|
+
|
5
|
+
module Inspec
|
6
|
+
module Plugins
|
7
|
+
# stores all CLI plugin, we expect those to the `Thor` subclasses
|
8
|
+
class CLI
|
9
|
+
def self.registry
|
10
|
+
@registry ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.register(klass, subcommand_name, usage, description, options = {})
|
14
|
+
registry[subcommand_name] = {
|
15
|
+
klass: klass,
|
16
|
+
subcommand_name: subcommand_name,
|
17
|
+
usage: usage,
|
18
|
+
description: description,
|
19
|
+
options: options,
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/inspec/profile.rb
CHANGED
@@ -19,29 +19,33 @@ module Inspec
|
|
19
19
|
attr_reader :path
|
20
20
|
attr_reader :metadata
|
21
21
|
|
22
|
+
# rubocop:disable Metrics/AbcSize
|
22
23
|
def initialize(options = nil)
|
23
24
|
@options = options || {}
|
24
|
-
|
25
|
-
@params = {}
|
26
25
|
@logger = options[:logger] || Logger.new(nil)
|
27
|
-
|
28
26
|
@path = @options[:path]
|
29
|
-
|
30
|
-
fail "Cannot find directory #{@path}" unless File.directory?(@path)
|
31
|
-
|
32
|
-
@metadata = read_metadata
|
33
|
-
@params = @metadata.params
|
34
|
-
# use the id from parameter, name or fallback to nil
|
35
|
-
@profile_id = options[:id] || params[:name] || nil
|
36
|
-
@params[:name] = @profile_id
|
27
|
+
@profile_id = options[:id]
|
37
28
|
|
38
|
-
@params[:rules] = rules = {}
|
39
29
|
@runner = Runner.new(
|
40
30
|
id: @profile_id,
|
41
31
|
backend: :mock,
|
42
32
|
test_collector: @options.delete(:test_collector),
|
43
33
|
)
|
44
|
-
|
34
|
+
|
35
|
+
# we're checking a profile, we don't care if it runs on the host machine
|
36
|
+
@options[:ignore_supports] = true
|
37
|
+
tests, libs, metadata = @runner.add_tests([@path], @options)
|
38
|
+
@content = tests + libs + metadata
|
39
|
+
|
40
|
+
# NB if you want to check more than one profile, use one
|
41
|
+
# Inspec::Profile#from_file per profile
|
42
|
+
@metadata_source = metadata.first
|
43
|
+
@metadata = Metadata.from_ref(@metadata_source[:ref], @metadata_source[:content], @profile_id, @logger)
|
44
|
+
@params = @metadata.params
|
45
|
+
@profile_id ||= params[:name]
|
46
|
+
@params[:name] = @profile_id
|
47
|
+
@params[:rules] = rules = {}
|
48
|
+
|
45
49
|
@runner.rules.each do |id, rule|
|
46
50
|
file = rule.instance_variable_get(:@__file)
|
47
51
|
rules[file] ||= {}
|
@@ -51,6 +55,7 @@ module Inspec
|
|
51
55
|
impact: rule.impact,
|
52
56
|
checks: rule.instance_variable_get(:@checks),
|
53
57
|
code: rule.instance_variable_get(:@__code),
|
58
|
+
source_location: rule.instance_variable_get(:@__source_location),
|
54
59
|
group_title: rule.instance_variable_get(:@__group_title),
|
55
60
|
}
|
56
61
|
end
|
@@ -84,55 +89,91 @@ module Inspec
|
|
84
89
|
# used to print information on errors and warnings which are found.
|
85
90
|
#
|
86
91
|
# @return [Boolean] true if no errors were found, false otherwise
|
87
|
-
def check # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
88
|
-
|
89
|
-
|
90
|
-
|
92
|
+
def check # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
93
|
+
# initial values for response object
|
94
|
+
result = {
|
95
|
+
summary: {
|
96
|
+
valid: false,
|
97
|
+
timestamp: Time.now.iso8601,
|
98
|
+
location: @path,
|
99
|
+
profile: nil,
|
100
|
+
controls: 0,
|
101
|
+
},
|
102
|
+
errors: [],
|
103
|
+
warnings: [],
|
104
|
+
}
|
105
|
+
|
106
|
+
entry = lambda { |file, line, column, control, msg|
|
107
|
+
{
|
108
|
+
file: file,
|
109
|
+
line: line,
|
110
|
+
column: column,
|
111
|
+
control_id: control,
|
112
|
+
msg: msg,
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
warn = lambda { |file, line, column, control, msg|
|
91
117
|
@logger.warn(msg)
|
92
|
-
|
118
|
+
result[:warnings].push(entry.call(file, line, column, control, msg))
|
93
119
|
}
|
94
|
-
|
120
|
+
|
121
|
+
error = lambda { |file, line, column, control, msg|
|
95
122
|
@logger.error(msg)
|
96
|
-
|
123
|
+
result[:errors].push(entry.call(file, line, column, control, msg))
|
97
124
|
}
|
98
125
|
|
99
126
|
@logger.info "Checking profile in #{@path}"
|
100
127
|
|
101
|
-
if
|
102
|
-
warn.call('The use of `metadata.rb` is deprecated. Use `inspec.yml`.')
|
128
|
+
if @content.any? { |h| h[:type] == :metadata && h[:ref] =~ /metadata\.rb$/ }
|
129
|
+
warn.call(Pathname.new(path).join('metadata.rb'), 0, 0, nil, 'The use of `metadata.rb` is deprecated. Use `inspec.yml`.')
|
103
130
|
end
|
104
131
|
|
105
|
-
|
132
|
+
# verify metadata
|
133
|
+
m_errors, m_warnings = @metadata.valid
|
134
|
+
m_errors.each { |msg| error.call(@metadata_source[:ref], 0, 0, nil, msg) }
|
135
|
+
m_warnings.each { |msg| warn.call(@metadata_source[:ref], 0, 0, nil, msg) }
|
136
|
+
m_unsupported = @metadata.unsupported
|
137
|
+
m_unsupported.each { |u| warn.call(@metadata_source[:ref], 0, 0, nil, "doesn't support: #{u}") }
|
138
|
+
@logger.info 'Metadata OK.' if m_errors.empty? && m_unsupported.empty?
|
139
|
+
|
140
|
+
# extract profile name
|
141
|
+
result[:summary][:profile] = @metadata.params[:name]
|
106
142
|
|
107
143
|
# check if the profile is using the old test directory instead of the
|
108
144
|
# new controls directory
|
109
|
-
if
|
110
|
-
warn.call('Profile uses deprecated `test` directory, rename it to `controls`.')
|
145
|
+
if @content.any? { |h| h[:type] == :test && h[:ref] =~ %r{test/[^/]+$} }
|
146
|
+
warn.call(Pathname.new(path).join('test'), 0, 0, nil, 'Profile uses deprecated `test` directory, rename it to `controls`.')
|
111
147
|
end
|
112
148
|
|
113
149
|
count = rules_count
|
150
|
+
result[:summary][:controls] = count
|
114
151
|
if count == 0
|
115
|
-
warn.call('No controls or tests were defined.')
|
152
|
+
warn.call(nil, nil, nil, nil, 'No controls or tests were defined.')
|
116
153
|
else
|
117
|
-
@logger.info("Found #{count}
|
154
|
+
@logger.info("Found #{count} controls.")
|
118
155
|
end
|
119
156
|
|
120
157
|
# iterate over hash of groups
|
121
|
-
@params[:rules].each
|
122
|
-
@logger.
|
123
|
-
|
124
|
-
|
158
|
+
@params[:rules].each { |group, controls|
|
159
|
+
@logger.info "Verify all controls in #{group}"
|
160
|
+
controls.each { |id, control|
|
161
|
+
sfile, sline = control[:source_location]
|
162
|
+
error.call(sfile, sline, nil, id, 'Avoid controls with empty IDs') if id.nil? or id.empty?
|
125
163
|
next if id.start_with? '(generated '
|
126
|
-
warn.call("
|
127
|
-
warn.call("
|
128
|
-
warn.call("
|
129
|
-
warn.call("
|
130
|
-
warn.call("
|
131
|
-
|
132
|
-
|
164
|
+
warn.call(sfile, sline, nil, id, "Control #{id} has no title") if control[:title].to_s.empty?
|
165
|
+
warn.call(sfile, sline, nil, id, "Control #{id} has no description") if control[:desc].to_s.empty?
|
166
|
+
warn.call(sfile, sline, nil, id, "Control #{id} has impact > 1.0") if control[:impact].to_f > 1.0
|
167
|
+
warn.call(sfile, sline, nil, id, "Control #{id} has impact < 0.0") if control[:impact].to_f < 0.0
|
168
|
+
warn.call(sfile, sline, nil, id, "Control #{id} has no tests defined") if control[:checks].nil? or control[:checks].empty?
|
169
|
+
}
|
170
|
+
}
|
133
171
|
|
134
|
-
|
135
|
-
|
172
|
+
# profile is valid if we could not find any error
|
173
|
+
result[:summary][:valid] = result[:errors].empty?
|
174
|
+
|
175
|
+
@logger.info 'Control definitions OK.' if result[:warnings].empty?
|
176
|
+
result
|
136
177
|
end
|
137
178
|
|
138
179
|
def rules_count
|
@@ -140,19 +181,18 @@ module Inspec
|
|
140
181
|
end
|
141
182
|
|
142
183
|
# generates a archive of a folder profile
|
184
|
+
# assumes that the profile was checked before
|
143
185
|
def archive(opts) # rubocop:disable Metrics/AbcSize
|
144
|
-
check_result = check
|
145
|
-
|
146
|
-
if check_result && !opts.ignore_errors == false
|
147
|
-
@logger.info 'Profile check failed. Please fix the profile before generating an archive.'
|
148
|
-
return false
|
149
|
-
end
|
150
|
-
|
151
186
|
profile_name = @params[:name]
|
152
187
|
|
153
188
|
ext = opts[:zip] ? 'zip' : 'tar.gz'
|
154
|
-
|
155
|
-
archive
|
189
|
+
|
190
|
+
if opts[:archive]
|
191
|
+
archive = Pathname.new(opts[:archive])
|
192
|
+
else
|
193
|
+
slug = profile_name.downcase.strip.tr(' ', '-').gsub(/[^\w-]/, '_')
|
194
|
+
archive = Pathname.new(File.dirname(__FILE__)).join('../..', "#{slug}.#{ext}")
|
195
|
+
end
|
156
196
|
|
157
197
|
# check if file exists otherwise overwrite the archive
|
158
198
|
if archive.exist? && !opts[:overwrite]
|
@@ -163,7 +203,7 @@ module Inspec
|
|
163
203
|
# remove existing archive
|
164
204
|
File.delete(archive) if archive.exist?
|
165
205
|
|
166
|
-
@logger.info "
|
206
|
+
@logger.info "Generate archive #{archive}."
|
167
207
|
|
168
208
|
# find all files
|
169
209
|
files = Dir.glob("#{path}/**/*")
|
@@ -195,16 +235,5 @@ module Inspec
|
|
195
235
|
@logger.info 'Finished archive generation.'
|
196
236
|
true
|
197
237
|
end
|
198
|
-
|
199
|
-
private
|
200
|
-
|
201
|
-
def read_metadata
|
202
|
-
mpath = Pathname.new(path).join('inspec.yml')
|
203
|
-
|
204
|
-
# fallback to metadata.rb if inspec.yml does not exist
|
205
|
-
# TODO deprecated, will be removed in InSpec 1.0
|
206
|
-
mpath = File.join(@path, 'metadata.rb') if !mpath.exist?
|
207
|
-
Metadata.from_file(mpath, @profile_id, @logger)
|
208
|
-
end
|
209
238
|
end
|
210
239
|
end
|
data/lib/inspec/rule.rb
CHANGED
@@ -53,6 +53,7 @@ module Inspec
|
|
53
53
|
@impact = nil
|
54
54
|
@__block = block
|
55
55
|
@__code = __get_block_source(&block)
|
56
|
+
@__source_location = __get_block_source_location(&block)
|
56
57
|
@title = nil
|
57
58
|
@desc = nil
|
58
59
|
# not changeable by the user:
|
@@ -166,5 +167,13 @@ module Inspec
|
|
166
167
|
rescue MethodSource::SourceNotFoundError
|
167
168
|
''
|
168
169
|
end
|
170
|
+
|
171
|
+
# get the source location of the block
|
172
|
+
def __get_block_source_location(&block)
|
173
|
+
return [nil, nil] unless block_given?
|
174
|
+
block.source_location
|
175
|
+
rescue MethodSource::SourceNotFoundError
|
176
|
+
[nil, nil]
|
177
|
+
end
|
169
178
|
end
|
170
179
|
end
|
data/lib/inspec/runner.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
# author: Dominik Richter
|
5
5
|
# author: Christoph Hartmann
|
6
6
|
|
7
|
+
require 'forwardable'
|
7
8
|
require 'uri'
|
8
9
|
require 'inspec/backend'
|
9
10
|
require 'inspec/profile_context'
|
@@ -13,6 +14,7 @@ require 'inspec/metadata'
|
|
13
14
|
|
14
15
|
module Inspec
|
15
16
|
class Runner # rubocop:disable Metrics/ClassLength
|
17
|
+
extend Forwardable
|
16
18
|
attr_reader :backend, :rules
|
17
19
|
def initialize(conf = {})
|
18
20
|
@rules = {}
|
@@ -64,6 +66,7 @@ module Inspec
|
|
64
66
|
|
65
67
|
tests = items.find_all { |i| i[:type] == :test }
|
66
68
|
libs = items.find_all { |i| i[:type] == :library }
|
69
|
+
meta = items.find_all { |i| i[:type] == :metadata }
|
67
70
|
|
68
71
|
# Ensure each test directory exists on the $LOAD_PATH. This
|
69
72
|
# will ensure traditional RSpec-isms like `require 'spec_helper'`
|
@@ -80,6 +83,8 @@ module Inspec
|
|
80
83
|
tests.flatten.each do |test|
|
81
84
|
add_content(test, libs)
|
82
85
|
end
|
86
|
+
|
87
|
+
[tests, libs, meta]
|
83
88
|
end
|
84
89
|
|
85
90
|
def create_context
|
@@ -106,9 +111,8 @@ module Inspec
|
|
106
111
|
end
|
107
112
|
end
|
108
113
|
|
109
|
-
|
110
|
-
|
111
|
-
end
|
114
|
+
def_delegator :@test_collector, :run
|
115
|
+
def_delegator :@test_collector, :report
|
112
116
|
|
113
117
|
private
|
114
118
|
|
data/lib/inspec/runner_rspec.rb
CHANGED
@@ -55,6 +55,11 @@ module Inspec
|
|
55
55
|
with.run_specs(tests)
|
56
56
|
end
|
57
57
|
|
58
|
+
def report
|
59
|
+
reporter = RSpec.configuration.formatters.find { |f| f.is_a? Inspec::RSpecReporter }
|
60
|
+
reporter.output_hash
|
61
|
+
end
|
62
|
+
|
58
63
|
private
|
59
64
|
|
60
65
|
# Empty the list of registered tests.
|
@@ -71,6 +76,12 @@ module Inspec
|
|
71
76
|
# @return [nil]
|
72
77
|
def configure_output
|
73
78
|
RSpec.configuration.add_formatter(@conf['format'] || 'progress')
|
79
|
+
|
80
|
+
setup_reporting if @conf['report']
|
81
|
+
end
|
82
|
+
|
83
|
+
def setup_reporting
|
84
|
+
RSpec.configuration.add_formatter(Inspec::RSpecReporter)
|
74
85
|
end
|
75
86
|
|
76
87
|
# Make sure that all RSpec example groups use the provided ID.
|
@@ -91,4 +102,12 @@ module Inspec
|
|
91
102
|
end
|
92
103
|
end
|
93
104
|
end
|
105
|
+
|
106
|
+
class RSpecReporter < RSpec::Core::Formatters::JsonFormatter
|
107
|
+
RSpec::Core::Formatters.register Inspec::RSpecReporter
|
108
|
+
|
109
|
+
def initialize(*)
|
110
|
+
super(StringIO.new)
|
111
|
+
end
|
112
|
+
end
|
94
113
|
end
|
@@ -23,17 +23,21 @@ module Inspec::Targets
|
|
23
23
|
fail "Don't know how to handle folder #{target}"
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
+
end
|
35
36
|
|
36
|
-
|
37
|
+
# FIXME(sr) dedup inspec/targets/folder
|
38
|
+
def collect(helper, files, getter)
|
39
|
+
return [] unless helper.respond_to? getter
|
40
|
+
helper.method(getter).call(files)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
data/lib/inspec/targets/tar.rb
CHANGED
@@ -39,9 +39,10 @@ module Inspec::Targets
|
|
39
39
|
elsif entry.file?
|
40
40
|
if files.include?(entry.full_name.gsub(rootdir, ''))
|
41
41
|
h = {
|
42
|
-
|
42
|
+
# NB if some file is empty, return empty-string, not nil
|
43
|
+
content: entry.read || '',
|
43
44
|
type: opts[:as] || :test,
|
44
|
-
|
45
|
+
ref: entry.full_name,
|
45
46
|
}
|
46
47
|
content.push(h)
|
47
48
|
end
|
data/lib/inspec/targets/url.rb
CHANGED
@@ -13,6 +13,8 @@ module Inspec::Targets
|
|
13
13
|
uri = URI.parse(target)
|
14
14
|
return false if uri.nil? or uri.scheme.nil?
|
15
15
|
%{ http https }.include? uri.scheme
|
16
|
+
rescue URI::Error => _e
|
17
|
+
false
|
16
18
|
end
|
17
19
|
|
18
20
|
def resolve(target, opts = {})
|
@@ -20,14 +22,13 @@ module Inspec::Targets
|
|
20
22
|
return nil unless target.start_with?('https://', 'http://')
|
21
23
|
|
22
24
|
# support for github url
|
23
|
-
m = %r{^https?://(www\.)?github\.com/(?<user>[\w-]+)/(?<repo>[\w-]+)(\.git)?$}.match(target)
|
25
|
+
m = %r{^https?://(www\.)?github\.com/(?<user>[\w-]+)/(?<repo>[\w-]+)(\.git)?(/)?$}.match(target)
|
24
26
|
if m
|
25
27
|
url = "https://github.com/#{m[:user]}/#{m[:repo]}/archive/master.tar.gz"
|
26
28
|
else
|
27
29
|
url = target
|
28
30
|
end
|
29
|
-
|
30
|
-
resolve_zip(url, opts)
|
31
|
+
resolve_archive(url, opts)
|
31
32
|
end
|
32
33
|
|
33
34
|
# download url into archive using opts,
|
@@ -47,7 +48,7 @@ module Inspec::Targets
|
|
47
48
|
[archive, remote.meta['content-type']]
|
48
49
|
end
|
49
50
|
|
50
|
-
def
|
51
|
+
def resolve_archive(url, opts)
|
51
52
|
archive, content_type = download_archive(url, Tempfile.new(['inspec-dl-', '.tar.gz']), opts)
|
52
53
|
|
53
54
|
# replace extension with zip if we detected a zip content type
|
data/lib/inspec/targets/zip.rb
CHANGED
@@ -18,9 +18,10 @@ module Inspec::Targets
|
|
18
18
|
while (entry = io.get_next_entry)
|
19
19
|
next if !files.include?(entry.name.gsub(rootdir, ''))
|
20
20
|
h = {
|
21
|
-
|
21
|
+
# NB if some file is empty, return empty-string, not nil
|
22
|
+
content: io.read || '',
|
22
23
|
type: opts[:as] || :test,
|
23
|
-
|
24
|
+
ref: entry.name,
|
24
25
|
}
|
25
26
|
content.push(h)
|
26
27
|
end
|
data/lib/inspec/version.rb
CHANGED