inspec-core 2.2.112 → 2.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -19
- data/README.md +1 -1
- data/docs/dev/integration-testing.md +31 -0
- data/docs/dev/plugins.md +4 -2
- data/docs/dsl_inspec.md +104 -4
- data/docs/plugins.md +57 -0
- data/docs/style.md +178 -0
- data/examples/plugins/inspec-resource-lister/Gemfile +12 -0
- data/examples/plugins/inspec-resource-lister/LICENSE +13 -0
- data/examples/plugins/inspec-resource-lister/README.md +62 -0
- data/examples/plugins/inspec-resource-lister/Rakefile +40 -0
- data/examples/plugins/inspec-resource-lister/inspec-resource-lister.gemspec +45 -0
- data/examples/plugins/inspec-resource-lister/lib/inspec-resource-lister.rb +16 -0
- data/examples/plugins/inspec-resource-lister/lib/inspec-resource-lister/cli_command.rb +70 -0
- data/examples/plugins/inspec-resource-lister/lib/inspec-resource-lister/plugin.rb +55 -0
- data/examples/plugins/inspec-resource-lister/lib/inspec-resource-lister/version.rb +10 -0
- data/examples/plugins/inspec-resource-lister/test/fixtures/README.md +24 -0
- data/examples/plugins/inspec-resource-lister/test/functional/README.md +18 -0
- data/examples/plugins/inspec-resource-lister/test/functional/inspec_resource_lister_test.rb +110 -0
- data/examples/plugins/inspec-resource-lister/test/helper.rb +26 -0
- data/examples/plugins/inspec-resource-lister/test/unit/README.md +17 -0
- data/examples/plugins/inspec-resource-lister/test/unit/cli_args_test.rb +64 -0
- data/examples/plugins/inspec-resource-lister/test/unit/plugin_def_test.rb +51 -0
- data/examples/profile/controls/example.rb +9 -8
- data/inspec-core.gemspec +1 -1
- data/lib/inspec/attribute_registry.rb +1 -1
- data/lib/inspec/globals.rb +4 -0
- data/lib/inspec/objects/control.rb +18 -3
- data/lib/inspec/plugin/v2.rb +14 -3
- data/lib/inspec/plugin/v2/activator.rb +7 -2
- data/lib/inspec/plugin/v2/installer.rb +426 -0
- data/lib/inspec/plugin/v2/loader.rb +137 -30
- data/lib/inspec/plugin/v2/registry.rb +13 -4
- data/lib/inspec/profile.rb +2 -1
- data/lib/inspec/reporters/json.rb +11 -1
- data/lib/inspec/resource.rb +6 -15
- data/lib/inspec/rule.rb +18 -9
- data/lib/inspec/runner_rspec.rb +1 -1
- data/lib/inspec/schema.rb +1 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-plugin-manager-cli/README.md +6 -0
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli.rb +18 -0
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +420 -0
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/plugin.rb +12 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/fixtures/config_dirs/empty/.gitkeep +0 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/inspec-egg-white-omelette/lib/inspec-egg-white-omelette.rb +2 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/inspec-egg-white-omelette/lib/inspec-egg-white-omelette/.gitkeep +0 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/inspec-wrong-structure/.gitkeep +0 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/wrong-name/lib/wrong-name.rb +1 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/wrong-name/lib/wrong-name/.gitkeep +0 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb +651 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/unit/cli_args_test.rb +71 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/unit/plugin_def_test.rb +20 -0
- data/lib/plugins/shared/core_plugin_test_helper.rb +101 -2
- data/lib/plugins/things-for-train-integration.rb +14 -0
- data/lib/resources/port.rb +10 -6
- metadata +38 -11
- data/docs/ruby_usage.md +0 -204
@@ -0,0 +1,71 @@
|
|
1
|
+
require_relative '../../../shared/core_plugin_test_helper.rb'
|
2
|
+
|
3
|
+
#-----------------------------------------------------------------------#
|
4
|
+
# Thor option defs
|
5
|
+
#-----------------------------------------------------------------------#
|
6
|
+
class PluginManagerCliOptions < MiniTest::Test
|
7
|
+
include CorePluginUnitHelper
|
8
|
+
let(:cli_class) { InspecPlugins::PluginManager::CliCommand }
|
9
|
+
|
10
|
+
def setup
|
11
|
+
require_relative '../../lib/inspec-plugin-manager-cli/cli_command'
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_list_args
|
15
|
+
arg_config = cli_class.all_commands['list'].options
|
16
|
+
assert_equal 1, arg_config.count, 'The list command should have 1 option'
|
17
|
+
|
18
|
+
assert_includes arg_config.keys, :all, 'The list command should have an --all option'
|
19
|
+
assert_equal :boolean, arg_config[:all].type, 'The --all option should be boolean'
|
20
|
+
assert_equal :a, arg_config[:all].aliases.first, 'The --all option should be aliased as -a'
|
21
|
+
refute_nil arg_config[:all].description, 'The --all option should have a description'
|
22
|
+
refute arg_config[:all].required, 'The --all option should not be required'
|
23
|
+
|
24
|
+
assert_equal 0, cli_class.instance_method(:list).arity, 'The list command should take no arguments'
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_search_args
|
28
|
+
arg_config = cli_class.all_commands['search'].options
|
29
|
+
assert_equal 2, arg_config.count, 'The search command should have 2 options'
|
30
|
+
|
31
|
+
assert_includes arg_config.keys, :all, 'The search command should have an --all option'
|
32
|
+
assert_equal :boolean, arg_config[:all].type, 'The --all option should be boolean'
|
33
|
+
assert_equal :a, arg_config[:all].aliases.first, 'The --all option should be aliased as -a'
|
34
|
+
refute_nil arg_config[:all].description, 'The --all option should have a description'
|
35
|
+
refute arg_config[:all].required, 'The --all option should not be required'
|
36
|
+
|
37
|
+
assert_includes arg_config.keys, :exact, 'The search command should have an --exact option'
|
38
|
+
assert_equal :boolean, arg_config[:exact].type, 'The --exact option should be boolean'
|
39
|
+
assert_equal :e, arg_config[:exact].aliases.first, 'The --exact option should be aliased as -e'
|
40
|
+
refute_nil arg_config[:exact].description, 'The --exact option should have a description'
|
41
|
+
refute arg_config[:exact].required, 'The --exact option should not be required'
|
42
|
+
|
43
|
+
assert_equal 1, cli_class.instance_method(:search).arity, 'The search command should take one argument'
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_install_args
|
47
|
+
arg_config = cli_class.all_commands['install'].options
|
48
|
+
assert_equal 1, arg_config.count, 'The install command should have 1 option'
|
49
|
+
|
50
|
+
assert_includes arg_config.keys, :version, 'The install command should have a --version option'
|
51
|
+
assert_equal :string, arg_config[:version].type, 'The --version option should be a string'
|
52
|
+
assert_equal :v, arg_config[:version].aliases.first, 'The --version option should be aliased as -v'
|
53
|
+
refute_nil arg_config[:version].description, 'The --version option should have a description'
|
54
|
+
refute arg_config[:version].required, 'The --version option should not be required'
|
55
|
+
|
56
|
+
assert_equal 1, cli_class.instance_method(:install).arity, 'The install command should take one argument'
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_update_args
|
60
|
+
# TODO: allow specifying version
|
61
|
+
arg_config = cli_class.all_commands['update'].options
|
62
|
+
assert_equal 0, arg_config.count, 'The update command should have no options'
|
63
|
+
assert_equal 1, cli_class.instance_method(:update).arity, 'The update command should take one argument'
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_uninstall_args
|
67
|
+
arg_config = cli_class.all_commands['uninstall'].options
|
68
|
+
assert_equal 0, arg_config.count, 'The uninstall command should have no options'
|
69
|
+
assert_equal 1, cli_class.instance_method(:uninstall).arity, 'The uninstall command should take one argument'
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../../../shared/core_plugin_test_helper.rb'
|
2
|
+
|
3
|
+
#-----------------------------------------------------------------------#
|
4
|
+
# Plugin Definition
|
5
|
+
#-----------------------------------------------------------------------#
|
6
|
+
class PluginManagerCliDefinitionTests < MiniTest::Test
|
7
|
+
include CorePluginUnitHelper
|
8
|
+
|
9
|
+
def test_plugin_registered
|
10
|
+
loader = Inspec::Plugin::V2::Loader.new
|
11
|
+
loader.load_all # We want to ensure it is auto-loaded
|
12
|
+
|
13
|
+
assert registry.known_plugin?(:'inspec-plugin-manager-cli'), 'inspec-plugin-manager-cli should be registered'
|
14
|
+
assert registry.loaded_plugin?(:'inspec-plugin-manager-cli'), 'inspec-plugin-manager-cli should be loaded'
|
15
|
+
|
16
|
+
status = registry[:'inspec-plugin-manager-cli']
|
17
|
+
assert_equal 2, status.api_generation, 'inspec-plugin-manager-cli should be v2'
|
18
|
+
assert_includes status.plugin_types, :cli_command, 'inspec-plugin-manager-cli should have cli_command activators'
|
19
|
+
end
|
20
|
+
end
|
@@ -11,12 +11,32 @@ require 'ostruct'
|
|
11
11
|
|
12
12
|
# Utilities often needed
|
13
13
|
require 'fileutils'
|
14
|
+
require 'tmpdir'
|
15
|
+
require 'pathname'
|
16
|
+
require 'forwardable'
|
14
17
|
|
15
18
|
# Configure MiniTest to expose things like `let`
|
16
19
|
class Module
|
17
20
|
include Minitest::Spec::DSL
|
18
21
|
end
|
19
22
|
|
23
|
+
module Inspec
|
24
|
+
class FuncTestRunResult
|
25
|
+
attr_reader :train_result
|
26
|
+
attr_reader :payload
|
27
|
+
|
28
|
+
extend Forwardable
|
29
|
+
def_delegator :train_result, :stdout
|
30
|
+
def_delegator :train_result, :stderr
|
31
|
+
def_delegator :train_result, :exit_status
|
32
|
+
|
33
|
+
def initialize(train_result)
|
34
|
+
@train_result = train_result
|
35
|
+
@payload = OpenStruct.new
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
20
40
|
module CorePluginBaseHelper
|
21
41
|
let(:repo_path) { File.expand_path(File.join(__FILE__, '..', '..', '..', '..')) }
|
22
42
|
let(:inspec_bin_path) { File.join(repo_path, 'bin', 'inspec') }
|
@@ -40,11 +60,90 @@ module CorePluginFunctionalHelper
|
|
40
60
|
elsif opts.key?(:env)
|
41
61
|
prefix = opts[:env].to_a.map { |assignment| "#{assignment[0]}=#{assignment[1]}" }.join(' ')
|
42
62
|
end
|
43
|
-
TRAIN_CONNECTION.run_command("#{prefix} #{inspec_bin_path} #{command_line}")
|
63
|
+
Inspec::FuncTestRunResult.new(TRAIN_CONNECTION.run_command("#{prefix} #{inspec_bin_path} #{command_line}"))
|
64
|
+
end
|
65
|
+
|
66
|
+
# This helper does some fancy footwork to make InSpec think a plugin
|
67
|
+
# under development is temporarily installed.
|
68
|
+
# @param String command_line Invocation, without the word 'inspec'
|
69
|
+
# @param Hash opts options as for run_inspec_process, with more options:
|
70
|
+
# :pre_run: Proc(plugin_statefile_data, tmp_dir_path) - optional setup block.
|
71
|
+
# Modify plugin_statefile_data as needed; it will be written to a plugins.json
|
72
|
+
# in tmp_dir_path. You may also copy in other things to the tmp_dir_path. Your PWD
|
73
|
+
# will be in the tmp_dir, and it will exist and be empty.
|
74
|
+
# :post_run: Proc(FuncTestRunResult, tmp_dir_path) - optional result capture block.
|
75
|
+
# run_result will be populated, but you can add more to the ostruct .payload
|
76
|
+
# Your PWD will be the tmp_dir, and it will still exist (for a moment!)
|
77
|
+
def run_inspec_process_with_this_plugin(command_line, opts = {})
|
78
|
+
plugin_path = __find_plugin_path_from_caller
|
79
|
+
|
80
|
+
# If it looks like it is a core plugin under test, don't add it to the plugin file
|
81
|
+
# since the loader will auto-load it anyway
|
82
|
+
if plugin_path.include?('lib/plugins/inspec-')
|
83
|
+
plugin_file_data = __make_empty_plugin_file_data_structure
|
84
|
+
else
|
85
|
+
plugin_file_data = __make_plugin_file_data_structure_with_path(plugin_path)
|
86
|
+
end
|
87
|
+
|
88
|
+
Dir.mktmpdir do |tmp_dir|
|
89
|
+
opts[:pre_run]&.call(plugin_file_data, tmp_dir)
|
90
|
+
plugin_file_path = File.join(tmp_dir, 'plugins.json')
|
91
|
+
# HACK: If the block cleared the hash, take that to mean it will provide a plugins.json file of its own.
|
92
|
+
File.write(plugin_file_path, JSON.generate(plugin_file_data)) unless plugin_file_data.empty?
|
93
|
+
opts[:env] ||= {}
|
94
|
+
opts[:env]['INSPEC_CONFIG_DIR'] = tmp_dir
|
95
|
+
run_result = run_inspec_process(command_line, opts)
|
96
|
+
|
97
|
+
# Read the resulting plugins.json into memory, if any
|
98
|
+
if File.exist?(plugin_file_path)
|
99
|
+
run_result.payload.plugin_data = JSON.parse(File.read(plugin_file_path))
|
100
|
+
end
|
101
|
+
|
102
|
+
opts[:post_run]&.call(run_result, tmp_dir)
|
103
|
+
run_result
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def __find_plugin_path_from_caller(frames_back = 2)
|
108
|
+
caller_path = Pathname.new(caller_locations(frames_back, 1).first.absolute_path)
|
109
|
+
# Typical caller path:
|
110
|
+
# /Users/cwolfe/sandbox/inspec-resource-lister/test/functional/inspec_resource_lister_test.rb
|
111
|
+
# We want:
|
112
|
+
# /Users/cwolfe/sandbox/inspec-resource-lister/lib/inspec-resource-lister.rb
|
113
|
+
cursor = caller_path
|
114
|
+
until cursor.basename.to_s == 'test' && cursor.parent.basename.to_s =~ /^(inspec|train)-/
|
115
|
+
cursor = cursor.parent
|
116
|
+
break if cursor.nil?
|
117
|
+
end
|
118
|
+
raise 'Could not comprehend plugin project directory structure' if cursor.nil?
|
119
|
+
|
120
|
+
project_dir = cursor.parent
|
121
|
+
plugin_name = project_dir.basename
|
122
|
+
entry_point = File.join(project_dir.to_s, 'lib', plugin_name.to_s + '.rb')
|
123
|
+
raise 'Could not find plugin entry point' unless File.exist?(entry_point)
|
124
|
+
entry_point
|
125
|
+
end
|
126
|
+
|
127
|
+
def __make_plugin_file_data_structure_with_path(path)
|
128
|
+
# TODO: dry this up, refs #3350
|
129
|
+
plugin_name = File.basename(path, '.rb')
|
130
|
+
data = __make_empty_plugin_file_data_structure
|
131
|
+
data['plugins'] << {
|
132
|
+
'name' => plugin_name,
|
133
|
+
'installation_type' => 'path',
|
134
|
+
'installation_path' => path,
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
def __make_empty_plugin_file_data_structure
|
139
|
+
# TODO: dry this up, refs #3350
|
140
|
+
{
|
141
|
+
'plugins_config_version' => '1.0.0',
|
142
|
+
'plugins' => [],
|
143
|
+
}
|
44
144
|
end
|
45
145
|
end
|
46
146
|
|
47
147
|
module CorePluginUnitHelper
|
48
148
|
include CorePluginBaseHelper
|
49
|
-
require 'inspec'
|
50
149
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# docs/plugins
|
2
|
+
# Update that train plugins are now possible
|
3
|
+
|
4
|
+
# test/unit/plugin/v2/loader_test.rb
|
5
|
+
# TODO: loading all plugins does not activate Train plugins
|
6
|
+
|
7
|
+
# lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb
|
8
|
+
# ~ Should be able to install a train plugin - in place, will fail until plugin published
|
9
|
+
# ~ Should be able to search for a train plugin - in place, will fail until plugin published
|
10
|
+
|
11
|
+
# test/functional/plugins_test.rb
|
12
|
+
# % Should be able to suggest a train transport plugin when an unsupported --target schema is used and a gem search is successful
|
13
|
+
# % Should be able to suggest a train transport plugin when an unrecognized profile platform declaration is used and a gem search is successful
|
14
|
+
# - Should be able to run inspec detect targeting a test target
|
data/lib/resources/port.rb
CHANGED
@@ -473,22 +473,26 @@ module Inspec::Resources
|
|
473
473
|
|
474
474
|
def parse_netstat_line(line)
|
475
475
|
# parse each line
|
476
|
-
# 1 - Proto, 2 - Recv-Q, 3 - Send-Q, 4 - Local Address, 5 - Foreign Address, 6 - State, 7 -
|
477
|
-
|
476
|
+
# 1 - Proto, 2 - Recv-Q, 3 - Send-Q, 4 - Local Address, 5 - Foreign Address, 6 - State, 7 - User, 8 - Inode, 9 - PID/Program name
|
477
|
+
# * UDP lines have an empty State column and the Busybox variant lacks
|
478
|
+
# the User and Inode columns.
|
479
|
+
reg = /^(?<proto>\S+)\s+(\S+)\s+(\S+)\s+(?<local_addr>\S+)\s+(?<foreign_addr>\S+)\s+(\S+)?\s+((\S+)\s+(\S+)\s+)?(?<pid_prog>\S+)/
|
480
|
+
parsed = reg.match(line)
|
481
|
+
|
478
482
|
return {} if parsed.nil? || line.match(/^proto/i)
|
479
483
|
|
480
484
|
# parse ip4 and ip6 addresses
|
481
|
-
protocol = parsed[
|
485
|
+
protocol = parsed[:proto].downcase
|
482
486
|
|
483
487
|
# detect protocol if not provided
|
484
|
-
protocol += '6' if parsed[
|
488
|
+
protocol += '6' if parsed[:local_addr].count(':') > 1 && %w{tcp udp}.include?(protocol)
|
485
489
|
|
486
490
|
# extract host and port information
|
487
|
-
host, port = parse_net_address(parsed[
|
491
|
+
host, port = parse_net_address(parsed[:local_addr], protocol)
|
488
492
|
return {} if host.nil?
|
489
493
|
|
490
494
|
# extract PID
|
491
|
-
process = parsed[
|
495
|
+
process = parsed[:pid_prog].split('/')
|
492
496
|
pid = process[0]
|
493
497
|
pid = pid.to_i if pid =~ /^\d+$/
|
494
498
|
process = process[1]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: train-core
|
@@ -16,20 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 1.4.37
|
19
|
+
version: '1.5'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '1.
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 1.4.37
|
26
|
+
version: '1.5'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: thor
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -308,6 +302,7 @@ files:
|
|
308
302
|
- docs/dev/control-eval.md
|
309
303
|
- docs/dev/filtertable-internals.md
|
310
304
|
- docs/dev/filtertable-usage.md
|
305
|
+
- docs/dev/integration-testing.md
|
311
306
|
- docs/dev/plugins.md
|
312
307
|
- docs/dsl_inspec.md
|
313
308
|
- docs/dsl_resource.md
|
@@ -318,6 +313,7 @@ files:
|
|
318
313
|
- docs/migration.md
|
319
314
|
- docs/platforms.md
|
320
315
|
- docs/plugin_kitchen_inspec.md
|
316
|
+
- docs/plugins.md
|
321
317
|
- docs/profiles.md
|
322
318
|
- docs/reporters.md
|
323
319
|
- docs/resources/aide_conf.md.erb
|
@@ -424,13 +420,13 @@ files:
|
|
424
420
|
- docs/resources/yum.md.erb
|
425
421
|
- docs/resources/zfs_dataset.md.erb
|
426
422
|
- docs/resources/zfs_pool.md.erb
|
427
|
-
- docs/ruby_usage.md
|
428
423
|
- docs/shared/matcher_be.md.erb
|
429
424
|
- docs/shared/matcher_cmp.md.erb
|
430
425
|
- docs/shared/matcher_eq.md.erb
|
431
426
|
- docs/shared/matcher_include.md.erb
|
432
427
|
- docs/shared/matcher_match.md.erb
|
433
428
|
- docs/shell.md
|
429
|
+
- docs/style.md
|
434
430
|
- examples/README.md
|
435
431
|
- examples/custom-resource/README.md
|
436
432
|
- examples/custom-resource/controls/example.rb
|
@@ -466,6 +462,22 @@ files:
|
|
466
462
|
- examples/meta-profile/README.md
|
467
463
|
- examples/meta-profile/controls/example.rb
|
468
464
|
- examples/meta-profile/inspec.yml
|
465
|
+
- examples/plugins/inspec-resource-lister/Gemfile
|
466
|
+
- examples/plugins/inspec-resource-lister/LICENSE
|
467
|
+
- examples/plugins/inspec-resource-lister/README.md
|
468
|
+
- examples/plugins/inspec-resource-lister/Rakefile
|
469
|
+
- examples/plugins/inspec-resource-lister/inspec-resource-lister.gemspec
|
470
|
+
- examples/plugins/inspec-resource-lister/lib/inspec-resource-lister.rb
|
471
|
+
- examples/plugins/inspec-resource-lister/lib/inspec-resource-lister/cli_command.rb
|
472
|
+
- examples/plugins/inspec-resource-lister/lib/inspec-resource-lister/plugin.rb
|
473
|
+
- examples/plugins/inspec-resource-lister/lib/inspec-resource-lister/version.rb
|
474
|
+
- examples/plugins/inspec-resource-lister/test/fixtures/README.md
|
475
|
+
- examples/plugins/inspec-resource-lister/test/functional/README.md
|
476
|
+
- examples/plugins/inspec-resource-lister/test/functional/inspec_resource_lister_test.rb
|
477
|
+
- examples/plugins/inspec-resource-lister/test/helper.rb
|
478
|
+
- examples/plugins/inspec-resource-lister/test/unit/README.md
|
479
|
+
- examples/plugins/inspec-resource-lister/test/unit/cli_args_test.rb
|
480
|
+
- examples/plugins/inspec-resource-lister/test/unit/plugin_def_test.rb
|
469
481
|
- examples/profile-attribute.yml
|
470
482
|
- examples/profile-attribute/README.md
|
471
483
|
- examples/profile-attribute/controls/example.rb
|
@@ -561,6 +573,7 @@ files:
|
|
561
573
|
- lib/inspec/plugin/v1/registry.rb
|
562
574
|
- lib/inspec/plugin/v2.rb
|
563
575
|
- lib/inspec/plugin/v2/activator.rb
|
576
|
+
- lib/inspec/plugin/v2/installer.rb
|
564
577
|
- lib/inspec/plugin/v2/loader.rb
|
565
578
|
- lib/inspec/plugin/v2/plugin_base.rb
|
566
579
|
- lib/inspec/plugin/v2/plugin_types/cli.rb
|
@@ -614,7 +627,21 @@ files:
|
|
614
627
|
- lib/plugins/inspec-init/lib/inspec-init/templates/profile/inspec.yml
|
615
628
|
- lib/plugins/inspec-init/lib/inspec-init/templates/profile/libraries/.gitkeep
|
616
629
|
- lib/plugins/inspec-init/test/functional/inspec_init_test.rb
|
630
|
+
- lib/plugins/inspec-plugin-manager-cli/README.md
|
631
|
+
- lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli.rb
|
632
|
+
- lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb
|
633
|
+
- lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/plugin.rb
|
634
|
+
- lib/plugins/inspec-plugin-manager-cli/test/fixtures/config_dirs/empty/.gitkeep
|
635
|
+
- lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/inspec-egg-white-omelette/lib/inspec-egg-white-omelette.rb
|
636
|
+
- lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/inspec-egg-white-omelette/lib/inspec-egg-white-omelette/.gitkeep
|
637
|
+
- lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/inspec-wrong-structure/.gitkeep
|
638
|
+
- lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/wrong-name/lib/wrong-name.rb
|
639
|
+
- lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/wrong-name/lib/wrong-name/.gitkeep
|
640
|
+
- lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb
|
641
|
+
- lib/plugins/inspec-plugin-manager-cli/test/unit/cli_args_test.rb
|
642
|
+
- lib/plugins/inspec-plugin-manager-cli/test/unit/plugin_def_test.rb
|
617
643
|
- lib/plugins/shared/core_plugin_test_helper.rb
|
644
|
+
- lib/plugins/things-for-train-integration.rb
|
618
645
|
- lib/resources/aide_conf.rb
|
619
646
|
- lib/resources/apache.rb
|
620
647
|
- lib/resources/apache_conf.rb
|
data/docs/ruby_usage.md
DELETED
@@ -1,204 +0,0 @@
|
|
1
|
-
# Using Ruby in InSpec
|
2
|
-
|
3
|
-
The InSpec DSL is a Ruby based DSL for writing audit controls, which
|
4
|
-
includes audit resources that you can invoke. Core and custom resources
|
5
|
-
are written as regular Ruby classes which inherit from
|
6
|
-
`Inspec.resource`.
|
7
|
-
|
8
|
-
Assuming we have a JSON file like this on the node to be tested:
|
9
|
-
|
10
|
-
```json
|
11
|
-
{
|
12
|
-
"keys":[
|
13
|
-
{"username":"john", "key":"/opt/keys/johnd.key"},
|
14
|
-
{"username":"jane", "key":"/opt/keys/janed.key"},
|
15
|
-
{"username":"sunny ", "key":"/opt/keys/sunnym.key"}
|
16
|
-
]
|
17
|
-
}
|
18
|
-
```
|
19
|
-
|
20
|
-
The following example shows how you can use pure Ruby code(variables,
|
21
|
-
loops, conditionals, regular expressions, etc) to run a few tests
|
22
|
-
against the above JSON file:
|
23
|
-
|
24
|
-
```ruby
|
25
|
-
control 'check-interns' do
|
26
|
-
# use the json InSpec resource to get the file
|
27
|
-
json_obj = json('/opt/keys/interns.json')
|
28
|
-
describe json_obj do
|
29
|
-
its('keys') { should_not eq nil }
|
30
|
-
end
|
31
|
-
if json_obj['keys']
|
32
|
-
# loop over the keys array
|
33
|
-
json_obj['keys'].each do |intern|
|
34
|
-
username = intern['username'].strip
|
35
|
-
# check for white spaces chars in usernames
|
36
|
-
describe username do
|
37
|
-
it { should_not match(/\s/) }
|
38
|
-
end
|
39
|
-
# check key file owners and permissions
|
40
|
-
describe file(intern['key']) do
|
41
|
-
it { should be_owned_by username }
|
42
|
-
its('mode') { should cmp '0600' }
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
```
|
48
|
-
|
49
|
-
## Execution
|
50
|
-
|
51
|
-
It's important to understand that Ruby code used in custom resources and
|
52
|
-
controls DSL is executed on the system that runs InSpec. This allows
|
53
|
-
InSpec to work without Ruby and rubygems being required on remote
|
54
|
-
targets(servers or containers).
|
55
|
-
|
56
|
-
For example, using `` `ls ``\` or `system('ls')` will result in the `ls`
|
57
|
-
command being run locally and not on the target(remote) system. In order
|
58
|
-
to process the output of `ls` executed on the target system, use
|
59
|
-
`inspec.command('ls')` or `inspec.powershell('ls')`
|
60
|
-
|
61
|
-
Similarly, use `inspec.file(PATH)` to access files or directories from
|
62
|
-
remote systems in your tests or custom resources.
|
63
|
-
|
64
|
-
## Using rubygems
|
65
|
-
|
66
|
-
Ruby gems are self-contained programs and libraries. If you create a custom
|
67
|
-
resource please vendor gems into the library. This ensures that all resources
|
68
|
-
are self-contained and complete and don't need any resolution at runtime. We
|
69
|
-
vendor resources and requirements through dependency resolution, which is
|
70
|
-
independent of programming languages and their resolver mechanisms.
|
71
|
-
|
72
|
-
## Interactive Debugging with Pry
|
73
|
-
|
74
|
-
Here's a sample InSpec control that users Ruby variables to instantiate
|
75
|
-
an InSpec resource once and use the content in multiple tests.
|
76
|
-
|
77
|
-
```ruby
|
78
|
-
control 'check-perl' do
|
79
|
-
impact 0.3
|
80
|
-
title 'Check perl compiled options and permissions'
|
81
|
-
perl_out = command('perl -V')
|
82
|
-
#require 'pry'; binding.pry;
|
83
|
-
describe perl_out do
|
84
|
-
its('exit_status') { should eq 0 }
|
85
|
-
its('stdout') { should match (/USE_64_BIT_ALL/) }
|
86
|
-
its('stdout') { should match (/useposix=true/) }
|
87
|
-
its('stdout') { should match (/-fstack-protector/) }
|
88
|
-
end
|
89
|
-
|
90
|
-
# extract an array of include directories
|
91
|
-
perl_inc = perl_out.stdout.partition('@INC:').last.strip.split("\n")
|
92
|
-
# ensure include directories are only writable by 'owner'
|
93
|
-
perl_inc.each do |path|
|
94
|
-
describe directory(path.strip) do
|
95
|
-
it { should_not be_writable.by('group') }
|
96
|
-
it { should_not be_writable.by('other') }
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
```
|
101
|
-
|
102
|
-
An **advanced** but very useful Ruby tip. In the previous example, I
|
103
|
-
commented out the `require 'pry'; binding.pry;` line. If you remove the
|
104
|
-
`#` prefix and run the control, the execution will stop at that line and
|
105
|
-
give you a `pry` shell. Use that to troubleshoot, print variables, see
|
106
|
-
methods available, etc. For the above example:
|
107
|
-
|
108
|
-
```ruby
|
109
|
-
[1] pry> perl_out.exit_status
|
110
|
-
=> 0
|
111
|
-
[2] pry> perl_out.stderr
|
112
|
-
=> ""
|
113
|
-
[3] pry> ls perl_out
|
114
|
-
Inspec::Plugins::Resource#methods: inspect
|
115
|
-
Inspec::Resources::Cmd#methods: command exist? exit_status result stderr stdout to_s
|
116
|
-
Inspec::Resource::Registry::Command#methods: inspec
|
117
|
-
instance variables: @__backend_runner__ @__resource_name__ @command @result
|
118
|
-
[4] pry> perl_out.stdout.partition('@INC:').last.strip.split("\n")
|
119
|
-
=> ["/Library/Perl/5.18/darwin-thread-multi-2level",
|
120
|
-
" /Library/Perl/5.18",
|
121
|
-
...REDACTED...
|
122
|
-
[5] pry> exit # or abort
|
123
|
-
```
|
124
|
-
|
125
|
-
You can use `pry` inside both the controls DSL and resources. Similarly,
|
126
|
-
for dev and test, you can use `inspec shell` which is based on `pry`,
|
127
|
-
for example:
|
128
|
-
|
129
|
-
```ruby
|
130
|
-
$ inspec shell
|
131
|
-
Welcome to the interactive InSpec Shell
|
132
|
-
To find out how to use it, type: help
|
133
|
-
|
134
|
-
inspec> command('ls /home/gordon/git/inspec/docs').stdout
|
135
|
-
=> "ctl_inspec.rst\ndsl_inspec.rst\ndsl_resource.rst\n"
|
136
|
-
inspec> command('ls').stdout.split("\n")
|
137
|
-
=> ["ctl_inspec.rst", "dsl_inspec.rst", "dsl_resource.rst"]
|
138
|
-
|
139
|
-
inspec> help command
|
140
|
-
Name: command
|
141
|
-
|
142
|
-
Description:
|
143
|
-
Use the command InSpec audit resource to test an arbitrary command that is run on the system.
|
144
|
-
|
145
|
-
Example:
|
146
|
-
describe command('ls -al /') do
|
147
|
-
it { should exist }
|
148
|
-
its('stdout') { should match /bin/ }
|
149
|
-
its('stderr') { should eq '' }
|
150
|
-
its('exit_status') { should eq 0 }
|
151
|
-
end
|
152
|
-
```
|
153
|
-
|
154
|
-
## Shelling out in tests
|
155
|
-
|
156
|
-
When writing tests you can not use standard ruby methods to shellout as it tries to execute those commands locally.
|
157
|
-
However, the `command` resource has a `.stdout` method that will allow you to manipulate the results.
|
158
|
-
Using the above example, you could check the writes on several subdirectories.
|
159
|
-
|
160
|
-
### Example 1
|
161
|
-
|
162
|
-
```ruby
|
163
|
-
$ inspec shell
|
164
|
-
Welcome to the interactive InSpec Shell
|
165
|
-
To find out how to use it, type: help
|
166
|
-
|
167
|
-
inspec> output=command('echo test').stdout
|
168
|
-
=> "test\n"
|
169
|
-
inspec> describe command('echo test') do
|
170
|
-
inspec> its('stdout') { should eq output }
|
171
|
-
inspec> end
|
172
|
-
|
173
|
-
Profile: inspec-shell
|
174
|
-
Version: (not specified)
|
175
|
-
|
176
|
-
Command echo
|
177
|
-
✔ test stdout should eq "test\n"
|
178
|
-
|
179
|
-
Test Summary: 1 successful, 0 failures, 0 skipped
|
180
|
-
```
|
181
|
-
|
182
|
-
### Example 2
|
183
|
-
|
184
|
-
```ruby
|
185
|
-
$ inspec shell
|
186
|
-
Welcome to the interactive InSpec Shell
|
187
|
-
To find out how to use it, type: help
|
188
|
-
|
189
|
-
inspec> dirs = command('ls -d /home/gordon/git/inspec/docs').stdout.split("\n")
|
190
|
-
=> ["/home/gordon/git/inspec/docs"]
|
191
|
-
inspec> dirs.each do |dir|
|
192
|
-
inspec> describe directory(dir) do
|
193
|
-
inspec> its('mode') { should cmp '0775' }
|
194
|
-
inspec> end
|
195
|
-
inspec> end
|
196
|
-
|
197
|
-
Profile: inspec-shell
|
198
|
-
Version: (not specified)
|
199
|
-
|
200
|
-
File /home/gordon/git/inspec/docs/
|
201
|
-
✔ mode should cmp == "0775"
|
202
|
-
|
203
|
-
Test Summary: 1 successful, 0 failures, 0 skipped
|
204
|
-
```
|