inspec-core 4.56.58 → 5.7.9
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/Gemfile +24 -9
- data/etc/deprecations.json +12 -11
- data/inspec-core.gemspec +3 -5
- data/lib/inspec/base_cli.rb +14 -2
- data/lib/inspec/cli.rb +16 -7
- data/lib/inspec/dependencies/dependency_set.rb +2 -6
- data/lib/inspec/dependency_installer.rb +74 -0
- data/lib/inspec/dependency_loader.rb +97 -0
- data/lib/inspec/dsl.rb +16 -23
- data/lib/inspec/env_printer.rb +1 -1
- data/lib/inspec/errors.rb +7 -0
- data/lib/inspec/fetcher/git.rb +28 -43
- data/lib/inspec/fetcher/url.rb +1 -1
- data/lib/inspec/formatters/base.rb +22 -0
- data/lib/inspec/metadata.rb +36 -0
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +44 -1
- data/lib/inspec/profile.rb +81 -29
- data/lib/inspec/reporters/automate.rb +1 -1
- data/lib/inspec/reporters/cli.rb +1 -1
- data/lib/inspec/reporters/json.rb +31 -11
- data/lib/inspec/resource.rb +6 -0
- data/lib/inspec/resources/cassandradb_session.rb +3 -4
- data/lib/inspec/resources/cron.rb +49 -0
- data/lib/inspec/resources/file.rb +1 -1
- data/lib/inspec/resources/ibmdb2_session.rb +3 -4
- data/lib/inspec/resources/ipfilter.rb +59 -0
- data/lib/inspec/resources/ipnat.rb +58 -0
- data/lib/inspec/resources/mongodb_session.rb +1 -7
- data/lib/inspec/resources/oracledb_session.rb +7 -20
- data/lib/inspec/resources/postgres_session.rb +5 -7
- data/lib/inspec/resources/processes.rb +4 -6
- data/lib/inspec/resources/service.rb +2 -4
- data/lib/inspec/resources.rb +3 -16
- data/lib/inspec/rule.rb +1 -1
- data/lib/inspec/runner.rb +18 -1
- data/lib/inspec/runner_rspec.rb +15 -0
- data/lib/inspec/schema/exec_json.rb +59 -58
- data/lib/inspec/schema/exec_json_min.rb +16 -16
- data/lib/inspec/schema/primitives.rb +68 -51
- data/lib/inspec/schema/profile_json.rb +27 -27
- data/lib/inspec/schema.rb +1 -0
- data/lib/inspec/secrets/yaml.rb +1 -7
- data/lib/inspec/ui.rb +1 -0
- data/lib/inspec/utils/deprecated_cloud_resources_list.rb +54 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec.rb +3 -0
- data/lib/matchers/matchers.rb +1 -7
- data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +9 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +126 -0
- data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +9 -8
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.erb +16 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/streaming_reporter.erb +31 -0
- data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +1 -1
- data/lib/plugins/inspec-init/templates/resources/basic/docs/resource-doc.erb +77 -0
- data/lib/plugins/inspec-init/templates/resources/basic/libraries/inspec-resource-template.erb +94 -0
- data/lib/plugins/inspec-init/templates/resources/plural/docs/resource-doc.erb +62 -0
- data/lib/plugins/inspec-init/templates/resources/plural/libraries/inspec-resource-template.erb +73 -0
- data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +6 -4
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +4 -1
- data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +2 -1
- data/lib/plugins/inspec-reporter-html2/templates/result.html.erb +1 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/README.md +5 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/plugin.rb +13 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +112 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/version.rb +8 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar.rb +15 -0
- metadata +24 -7
@@ -0,0 +1,126 @@
|
|
1
|
+
require_relative "renderer"
|
2
|
+
|
3
|
+
module InspecPlugins
|
4
|
+
module Init
|
5
|
+
class CLI < Inspec.plugin(2, :cli_command)
|
6
|
+
#-------------------------------------------------------------------#
|
7
|
+
# inspec init resource
|
8
|
+
#-------------------------------------------------------------------#
|
9
|
+
desc "resource RESOURCE_NAME [options]", "Generates an InSpec resource, which can extend the scope of InSpec resources support"
|
10
|
+
# General options
|
11
|
+
option :prompt, type: :boolean, default: true, desc: "Interactively prompt for information to put in your generated resource."
|
12
|
+
option :overwrite, type: :boolean, default: false, desc: "Overwrite existing files"
|
13
|
+
option :layout, type: :string, default: "resource-pack", desc: "File layout, either 'resource-pack' or 'core'"
|
14
|
+
option :template, type: :string, default: "basic", desc: "Which type of resource template to use"
|
15
|
+
|
16
|
+
# Templating vars
|
17
|
+
option :supports_platform, type: :string, default: "linux", desc: "the platform supported by this resource"
|
18
|
+
option :description, type: :string, default: "Resource description ...", desc: "the description of this resource"
|
19
|
+
option :class_name, type: :string, default: "MyCustomResource", desc: "Class Name for your resource."
|
20
|
+
option :path, type: :string, default: ".", desc: "Subdirectory under which to create files"
|
21
|
+
|
22
|
+
# Wishlist:
|
23
|
+
# Make make_rename_map_resource dynamic:
|
24
|
+
# + Add a --path option which defaults to ., which will create the tree under that path
|
25
|
+
# + Add a --layout option which changes all the tree to act as placing the files in core inspec (lib/inspec/resources, docs-chef-io/)
|
26
|
+
# - Add a --template=plural option which changes the templates to use a set of Filtertable based templates
|
27
|
+
# - Add a --template=inherit option which provides a template for inheriting from the core resources
|
28
|
+
# - Add a template=aws
|
29
|
+
# + Generate properties and matchers:
|
30
|
+
# + generate a has_bells? matcher => it { should have_bells }
|
31
|
+
# + generate a is_purple? matcher => it { should be_purple }
|
32
|
+
# + generate a shoe_size => its('shoe_size') { should cmp 10 }
|
33
|
+
# + Generate unit tests for above properties and matchers
|
34
|
+
# + Generate docs for properties and matchers
|
35
|
+
# + Add --overwrite option
|
36
|
+
|
37
|
+
def resource(resource_name)
|
38
|
+
resource_vars_from_opts_resource
|
39
|
+
template_vars = {
|
40
|
+
name: options[:path], # This is used for the path prefix
|
41
|
+
resource_name: resource_name,
|
42
|
+
}
|
43
|
+
template_vars.merge!(options)
|
44
|
+
template_path = File.join("resources", template_vars["template"])
|
45
|
+
|
46
|
+
render_opts = {
|
47
|
+
templates_path: TEMPLATES_PATH,
|
48
|
+
overwrite: options[:overwrite],
|
49
|
+
file_rename_map: make_rename_map_resource(template_vars),
|
50
|
+
}
|
51
|
+
renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
|
52
|
+
renderer.render_with_values(template_path, "resource", template_vars)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def make_rename_map_resource(vars)
|
58
|
+
if vars["layout"] == "resource-pack"
|
59
|
+
{
|
60
|
+
File.join("libraries", "inspec-resource-template.erb") => File.join("libraries", vars[:resource_name] + ".rb"),
|
61
|
+
File.join("docs", "resource-doc.erb") => File.join("docs", vars[:resource_name] + ".md"),
|
62
|
+
File.join("test", "unit", "inspec-resource-test-template.erb") => File.join("test", "unit", vars[:resource_name] + "_test.rb"),
|
63
|
+
}
|
64
|
+
elsif vars["layout"] == "core"
|
65
|
+
{
|
66
|
+
File.join("libraries", "inspec-resource-template.erb") => File.join("lib", "inspec", "resources", vars[:resource_name] + ".rb"),
|
67
|
+
File.join("docs", "resource-doc.erb") => File.join("docs-chef-io", "content", "inspec", "resources", vars[:resource_name] + ".md"),
|
68
|
+
File.join("test", "unit", "inspec-resource-test-template.erb") => File.join("test", "unit", "resources", vars[:resource_name] + "_test.rb"),
|
69
|
+
}
|
70
|
+
else
|
71
|
+
ui.error("Unrecognized value for 'layout' - please enter either 'resource-pack' or 'core'")
|
72
|
+
ui.exit(:usage_error)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def resource_vars_from_opts_resource
|
77
|
+
if options[:prompt] && ui.interactive?
|
78
|
+
options.dup.merge(prompt_for_options_resource)
|
79
|
+
elsif !options[:prompt]
|
80
|
+
# Nothing to do - unless we need to calculate dynamic defaults in the future
|
81
|
+
else
|
82
|
+
ui.error("You requested interactive prompting for the template variables, but this does not seem to be an interactive terminal.")
|
83
|
+
ui.exit(:usage_error)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def prompt_for_options_resource # rubocop: disable Metrics/AbcSize
|
88
|
+
option_defs = self.class.all_commands["resource"].options
|
89
|
+
options_order = {
|
90
|
+
path: {},
|
91
|
+
layout: {
|
92
|
+
mode: :select,
|
93
|
+
choices: [
|
94
|
+
{ name: "Resource Pack", value: "resource-pack", default: true },
|
95
|
+
{ name: "InSpec Core", value: "core" },
|
96
|
+
],
|
97
|
+
},
|
98
|
+
template: {
|
99
|
+
mode: :select,
|
100
|
+
choices: [
|
101
|
+
{ name: "Basic", value: "basic", default: true },
|
102
|
+
{ name: "Plural", value: "plural" },
|
103
|
+
],
|
104
|
+
},
|
105
|
+
supports_platform: {},
|
106
|
+
description: {},
|
107
|
+
class_name: {},
|
108
|
+
}
|
109
|
+
|
110
|
+
options_order.each do |opt_name, prompt_options|
|
111
|
+
opt_def = option_defs[opt_name]
|
112
|
+
|
113
|
+
case prompt_options[:mode]
|
114
|
+
when :select
|
115
|
+
options[opt_name] = ui.prompt.select("Choose " + opt_def.description + ":", prompt_options[:choices])
|
116
|
+
when :multiline
|
117
|
+
options[opt_name] = ui.prompt.multiline("Enter " + opt_def.description + ". Press Control-D to end.", default: options[opt_name])
|
118
|
+
else
|
119
|
+
# Assume plain ask
|
120
|
+
options[opt_name] = ui.prompt.ask("Enter " + opt_def.description + ":", default: options[opt_name])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -38,8 +38,8 @@ module InspecPlugins
|
|
38
38
|
full_destination_path = Pathname.new(Dir.pwd).join(relative_destination_path)
|
39
39
|
|
40
40
|
# check that the directory does not exist
|
41
|
-
if File.exist?(full_destination_path) && !overwrite_mode
|
42
|
-
ui.plain_line "#{ui.emphasis(full_destination_path)} exists already, use --overwrite"
|
41
|
+
if File.exist?(full_destination_path) && !overwrite_mode && template_values[:name] != "."
|
42
|
+
ui.plain_line "#{ui.emphasis(full_destination_path)} exists already, use --overwrite or move to #{ui.emphasis(full_destination_path)} to create the resource"
|
43
43
|
ui.exit(:usage_error)
|
44
44
|
end
|
45
45
|
|
@@ -57,18 +57,19 @@ module InspecPlugins
|
|
57
57
|
|
58
58
|
relative_destination_item_path = file_rename_map[relative_destination_item_path] || relative_destination_item_path
|
59
59
|
full_destination_item_path = Pathname.new(full_destination_path).join(relative_destination_item_path)
|
60
|
-
if File.
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
if File.file?(source_file)
|
61
|
+
# Be git-like and only create directories if they contain a file
|
62
|
+
containing_directory = full_destination_item_path.dirname
|
63
|
+
unless File.exist?(containing_directory)
|
64
|
+
ui.list_item "Creating directory #{ui.emphasis(containing_directory)}"
|
65
|
+
FileUtils.mkdir_p(containing_directory)
|
66
|
+
end
|
64
67
|
ui.list_item "Creating file #{ui.emphasis(relative_destination_item_path)}"
|
65
68
|
# read & render content
|
66
69
|
content = render(File.read(source_file), template_values)
|
67
70
|
# write file content
|
68
71
|
|
69
72
|
File.write(full_destination_item_path, content)
|
70
|
-
else
|
71
|
-
ui.warning "Ignoring #{ui.emphasis(source_file)}, because its not an file or directoy"
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
@@ -66,6 +66,22 @@ module InspecPlugins
|
|
66
66
|
InspecPlugins::<%= module_name %>::Reporter
|
67
67
|
end
|
68
68
|
<% end %>
|
69
|
+
|
70
|
+
<% if activators[:streaming_reporter] %>
|
71
|
+
# Define a new Streaming Reporter.
|
72
|
+
# The argument here will be used to match against the CLI --reporter option.
|
73
|
+
# `--reporter <%= streaming_reporter_name_snake %>` will load your streaming reporter and perform streaming real-time on each passing, failing or pending test.
|
74
|
+
streaming_reporter :<%= streaming_reporter_name_snake %> do
|
75
|
+
# Calling this activator doesn't mean the reporter is being executed - just
|
76
|
+
# that we should be ready to do so. So, load the file that defines the
|
77
|
+
# functionality.
|
78
|
+
require "<%= plugin_name %>/streaming_reporter"
|
79
|
+
|
80
|
+
# Having loaded our functionality, return a class that will let the
|
81
|
+
# reporting engine tap into it.
|
82
|
+
InspecPlugins::<%= module_name %>::StreamingReporter
|
83
|
+
end
|
84
|
+
<% end %>
|
69
85
|
end
|
70
86
|
end
|
71
87
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module InspecPlugins::<%= module_name %>
|
2
|
+
# This class will provide the actual Streaming Reporter implementation.
|
3
|
+
# Its superclass is provided by another call to Inspec.plugin,
|
4
|
+
# this time with two args. The first arg specifies we are requesting
|
5
|
+
# version 2 of the Plugins API. The second says we are making a
|
6
|
+
# Streaming Reporter plugin component, so please make available any DSL needed
|
7
|
+
# for that.
|
8
|
+
|
9
|
+
class StreamingReporter < Inspec.plugin(2, :streaming_reporter)
|
10
|
+
|
11
|
+
# Registering these methods with RSpec::Core::Formatters class is mandatory
|
12
|
+
RSpec::Core::Formatters.register self, :example_passed, :example_failed, :example_pending
|
13
|
+
|
14
|
+
def initialize(output)
|
15
|
+
@output = output
|
16
|
+
end
|
17
|
+
|
18
|
+
def example_passed(notification) # ExampleNotification
|
19
|
+
# some logic to run on passing test case
|
20
|
+
end
|
21
|
+
|
22
|
+
def example_failed(notification) # FailedExampleNotification
|
23
|
+
# some logic to run on failing test case
|
24
|
+
end
|
25
|
+
|
26
|
+
def example_pending(notification) # ExampleNotification
|
27
|
+
# some logic to run on pending test case
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
+++
|
2
|
+
title = "<%= resource_name %> resource"
|
3
|
+
draft = false
|
4
|
+
gh_repo = "inspec"
|
5
|
+
platform = "<%= supports_platform %>"
|
6
|
+
|
7
|
+
[menu]
|
8
|
+
[menu.inspec]
|
9
|
+
title = "<%= resource_name %>"
|
10
|
+
identifier = "inspec/resources/os/<%= resource_name %>.md <%= resource_name %> resource"
|
11
|
+
parent = "inspec/resources/os"
|
12
|
+
+++
|
13
|
+
|
14
|
+
Use the `<%= resource_name %>` Chef InSpec audit resource to test the ...
|
15
|
+
|
16
|
+
|
17
|
+
## Availability
|
18
|
+
|
19
|
+
### Installation
|
20
|
+
|
21
|
+
This resource is distributed along with Chef InSpec itself. You can use it automatically.
|
22
|
+
|
23
|
+
## Syntax
|
24
|
+
|
25
|
+
A `<%= resource_name %>` Chef InSpec audit resource ...
|
26
|
+
|
27
|
+
describe <%= resource_name %> do
|
28
|
+
its('shoe_size') { should cmp 42 }
|
29
|
+
it { should be_purple }
|
30
|
+
it { should have_bells }
|
31
|
+
end
|
32
|
+
where
|
33
|
+
|
34
|
+
- `'shoe_size'` is some property of this resource
|
35
|
+
- `42` is the value to test for shoe size
|
36
|
+
- `be_purple` is a matcher of this resource
|
37
|
+
- `have_bells` is a matcher of this resource
|
38
|
+
|
39
|
+
## Properties
|
40
|
+
|
41
|
+
- Properties of the resources: `shoe_size`
|
42
|
+
|
43
|
+
### shoe_size
|
44
|
+
|
45
|
+
The shoe_size property tests ....
|
46
|
+
|
47
|
+
## Matchers
|
48
|
+
|
49
|
+
For a full list of available matchers, please visit our [matchers page](https://docs.chef.io/inspec/matchers/).
|
50
|
+
|
51
|
+
The specific matchers of this resource are: `be_purple`, `have_bells`
|
52
|
+
|
53
|
+
### be_purple
|
54
|
+
|
55
|
+
The `be_purple` matcher tests the ...:
|
56
|
+
|
57
|
+
it { should be_purple }
|
58
|
+
|
59
|
+
## Examples
|
60
|
+
The following examples show how to use this Chef InSpec audit resource.
|
61
|
+
|
62
|
+
### Example 1
|
63
|
+
|
64
|
+
`shoe_size` returns ...
|
65
|
+
|
66
|
+
describe <%= resource_name %> do
|
67
|
+
its("shoe_size") { should eq 42 }
|
68
|
+
end
|
69
|
+
|
70
|
+
### Example 2
|
71
|
+
|
72
|
+
`be_purple` checks for ...
|
73
|
+
|
74
|
+
describe <%= resource_name %> do
|
75
|
+
it { should be_purple }
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# Uncomment the below lines to add gems and files required by the resource
|
2
|
+
# require ""
|
3
|
+
# require_relative ""
|
4
|
+
|
5
|
+
# Change module if required
|
6
|
+
module Inspec::Resources
|
7
|
+
# Most custom InSpec resource inherit from a dynamic class, InSpec.resource(1).
|
8
|
+
# If you wish to inherit from a core resource, you need to follow special instructions -
|
9
|
+
# see https://www.chef.io/blog/extending-inspec-resources-core-resource-inheritance
|
10
|
+
class <%= class_name %> < Inspec.resource(1)
|
11
|
+
# Every resource requires an internal name.
|
12
|
+
name "<%= resource_name %>"
|
13
|
+
|
14
|
+
# Restrict to only run on the below platforms (if none were given,
|
15
|
+
# all OS's and cloud API's supported)
|
16
|
+
supports platform: "<%= supports_platform %>"
|
17
|
+
|
18
|
+
desc "<%= description %>"
|
19
|
+
|
20
|
+
example <<~EXAMPLE
|
21
|
+
describe "<%= resource_name %>" do
|
22
|
+
its("shoe_size") { should cmp 10 }
|
23
|
+
end
|
24
|
+
describe "<%= resource_name %>" do
|
25
|
+
it { should be_purple }
|
26
|
+
end
|
27
|
+
EXAMPLE
|
28
|
+
|
29
|
+
# Resource initialization. Add any arguments you want to pass to the contructor here.
|
30
|
+
# Anything you pass here will be passed to the "describe" call:
|
31
|
+
# describe <%= resource_name %>(YOUR_PARAMETERS_HERE) do
|
32
|
+
# its("shoe_size") { should cmp 10 }
|
33
|
+
# end
|
34
|
+
def initialize
|
35
|
+
skip_resource "The `<%= resource_name %>` resource is not yet available on your OS." unless inspec.os.<%= supports_platform %>?
|
36
|
+
# Initialize required path/params/configs
|
37
|
+
end
|
38
|
+
|
39
|
+
# Define a resource ID. This is used in reporting engines to uniquely identify the individual resource.
|
40
|
+
# This might be a file path, or a process ID, or a cloud instance ID. Only meaningful to the implementation.
|
41
|
+
# Must be a string. Defaults to the empty string if not implemented.
|
42
|
+
def resource_id
|
43
|
+
# replace value specific unique to this individual resource instance
|
44
|
+
"something special"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Define how you want your resource to appear in test reports. Commonly, this is just the resource name and the resource ID.
|
48
|
+
def to_s
|
49
|
+
"<%= resource_name %> #{resource_id}"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Define matchers. Matchers are predicates - they return true or false.
|
53
|
+
# Matchers also have their names transformed: the question mark is dropped, and
|
54
|
+
# the "is_" prefix becomes "be_". A similar transformation happens for "has_" (see below)
|
55
|
+
# So this will be called as:
|
56
|
+
# describe "<%= resource_name %>" do
|
57
|
+
# it { should be_purple }
|
58
|
+
# end
|
59
|
+
def is_purple?
|
60
|
+
# positive or negative expectations specific to this resource instance
|
61
|
+
true # Purple is the best color
|
62
|
+
end
|
63
|
+
|
64
|
+
# Define matchers. Matchers are predicates - they return true or false.
|
65
|
+
# Matchers also have their names transformed: the question mark is dropped, and
|
66
|
+
# the "has_" prefix becomes "have_".
|
67
|
+
# So this will be called as:
|
68
|
+
# describe "<%= resource_name %>" do
|
69
|
+
# it { should have_bells }
|
70
|
+
# end
|
71
|
+
def has_bells?
|
72
|
+
# positive or negative expectations specific to this resource instance
|
73
|
+
true # Jingle all the way
|
74
|
+
end
|
75
|
+
|
76
|
+
# Define properties. Properties return values for evaluation against operators.
|
77
|
+
# No name transformation occurs. This is called using the "its" facility.
|
78
|
+
# So this will be called as:
|
79
|
+
# describe "<%= resource_name %>" do
|
80
|
+
# its('shoe_size') { should cmp 42 }
|
81
|
+
# end
|
82
|
+
def shoe_size
|
83
|
+
# Implementation of a property specific to this resource
|
84
|
+
42
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
# Methods to help the resource's public methods
|
90
|
+
def helper_method
|
91
|
+
# Add anything you need here
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
+++
|
2
|
+
title = "<%= resource_name %> resource"
|
3
|
+
draft = false
|
4
|
+
gh_repo = "inspec"
|
5
|
+
platform = "<%= supports_platform %>"
|
6
|
+
|
7
|
+
[menu]
|
8
|
+
[menu.inspec]
|
9
|
+
title = "<%= resource_name %>"
|
10
|
+
identifier = "inspec/resources/os/<%= resource_name %>.md <%= resource_name %> resource"
|
11
|
+
parent = "inspec/resources/os"
|
12
|
+
+++
|
13
|
+
|
14
|
+
Use the `<%= resource_name %>` Chef InSpec audit resource to test multiple ...
|
15
|
+
|
16
|
+
|
17
|
+
## Availability
|
18
|
+
|
19
|
+
### Installation
|
20
|
+
|
21
|
+
This resource is distributed along with Chef InSpec itself. You can use it automatically.
|
22
|
+
|
23
|
+
## Syntax
|
24
|
+
|
25
|
+
A `<%= resource_name %>` Chef InSpec audit resource tests multiple ...
|
26
|
+
|
27
|
+
describe <%= resource_name %>.where { shoe_size > 10 } do
|
28
|
+
its('count') { should cmp 10 }
|
29
|
+
end
|
30
|
+
|
31
|
+
where
|
32
|
+
|
33
|
+
- `'shoe_size'` is a filter criteria of this resource
|
34
|
+
- `10` is the value to test for shoe size
|
35
|
+
- `count` is the count of matched records
|
36
|
+
|
37
|
+
## Filter Criteria
|
38
|
+
|
39
|
+
### shoe_size
|
40
|
+
|
41
|
+
The shoe_size filter criteria tests ....
|
42
|
+
|
43
|
+
## Properties
|
44
|
+
|
45
|
+
### count
|
46
|
+
|
47
|
+
Returns the number of records matched by the filter criteria.
|
48
|
+
|
49
|
+
describe <%= resource_name %>.where { shoe_size > 10 } do
|
50
|
+
its('count') { should cmp 10 }
|
51
|
+
end
|
52
|
+
|
53
|
+
## Matchers
|
54
|
+
|
55
|
+
### exist
|
56
|
+
|
57
|
+
The control will pass if the filter returns at least one result. Use
|
58
|
+
`should_not` if you expect zero matches.
|
59
|
+
|
60
|
+
describe <%= resource_name %> do
|
61
|
+
it { should exist }
|
62
|
+
end
|
data/lib/plugins/inspec-init/templates/resources/plural/libraries/inspec-resource-template.erb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# This file was generated by `inspec init resource <%= resource_name %>`
|
2
|
+
# using the "--template plural" option. It represents a "plural" (FilterTable-based)
|
3
|
+
# InSpec resource.
|
4
|
+
|
5
|
+
# Plural resources query multiple resources of the same type in bulk. For details of the
|
6
|
+
# differences between singular and plural resources, please see:
|
7
|
+
# https://www.chef.io/blog/understanding-singular-and-plural-inspec-resources
|
8
|
+
|
9
|
+
# Plural resources rely on the FilterTable facility to handle data lookup and querying.
|
10
|
+
# For details on Filtertable and how to use it effectively within your resource, please see
|
11
|
+
# https://github.com/inspec/inspec/blob/main/dev-docs/filtertable-usage.md
|
12
|
+
# Consider that page required reading for authoring plural resources.
|
13
|
+
|
14
|
+
# Uncomment the below lines to add gems and files required by the resource
|
15
|
+
# require "inspec/utils/filter"
|
16
|
+
# require_relative ""
|
17
|
+
|
18
|
+
# Include FilterTable support
|
19
|
+
require "inspec/utils/filter"
|
20
|
+
|
21
|
+
module Inspec::Resources
|
22
|
+
# Most custom InSpec resource inherit from a dynamic class, InSpec.resource(1).
|
23
|
+
# If you wish to inherit from a core resource, you need to follow special instructions -
|
24
|
+
# see https://www.chef.io/blog/extending-inspec-resources-core-resource-inheritance
|
25
|
+
class <%= class_name %> < Inspec.resource(1)
|
26
|
+
# Every resource requires an internal name.
|
27
|
+
name "<%= resource_name %>"
|
28
|
+
|
29
|
+
# Restrict to only run on the below platforms (if none were given,
|
30
|
+
# all OS's and cloud API's supported)
|
31
|
+
supports platform: "<%= supports_platform %>"
|
32
|
+
|
33
|
+
desc "<%= description %>"
|
34
|
+
|
35
|
+
example <<~EXAMPLE
|
36
|
+
describe <%= resource_name %>.where{ shoe_size > 10 } do
|
37
|
+
its("count") { should cmp 0 }
|
38
|
+
end
|
39
|
+
EXAMPLE
|
40
|
+
|
41
|
+
# Resource initialization. Add any arguments you want to pass to the contructor here.
|
42
|
+
# Anything you pass here will be passed to the "describe" call:
|
43
|
+
# describe <%= resource_name %>(YOUR_PARAMETERS_HERE) do
|
44
|
+
# its("shoe_size") { should cmp 10 }
|
45
|
+
# end
|
46
|
+
def initialize
|
47
|
+
# Initialize required path/params/configs
|
48
|
+
end
|
49
|
+
|
50
|
+
# Define the FilterTable. This will define many extra methods on your resource, including
|
51
|
+
# where(), count(), and a property for every column.
|
52
|
+
table = FilterTable.create
|
53
|
+
table.register_column(:names, field: :name, style: :simple)
|
54
|
+
.register_column(:shoe_sizes, field: :shoe_size)
|
55
|
+
.install_filter_methods_on_resource(self, :fetch_data)
|
56
|
+
|
57
|
+
# Plural resources do not generally define a resource_id.
|
58
|
+
|
59
|
+
# Define how you want your resource to appear in test reports. Commonly, this is just the resource name for plural resources.
|
60
|
+
def to_s
|
61
|
+
"<%= resource_name %>"
|
62
|
+
end
|
63
|
+
|
64
|
+
# Do whatever you need to do to fetch the underlying data.
|
65
|
+
# Return it as an array of hashes.
|
66
|
+
def fetch_data
|
67
|
+
[
|
68
|
+
{ name: "Bob", shoe_size: 9 },
|
69
|
+
{ name: "Alice", shoe_size: 8 },
|
70
|
+
]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -7,31 +7,33 @@
|
|
7
7
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
8
8
|
<style type="text/css">
|
9
9
|
/* Must inline all CSS files, this is a single-file output that may be airgapped */
|
10
|
-
<%= ERB.new(File.read(css_path),
|
10
|
+
<%= ERB.new(File.read(css_path), nil, nil, "_css").result(binding) %>
|
11
11
|
</style>
|
12
12
|
<script type="text/javascript">
|
13
13
|
// <![CDATA[
|
14
14
|
/* Must inline all JavaScript files, this is a single-file output that may be airgapped */
|
15
|
-
<%= ERB.new(File.read(js_path),
|
15
|
+
<%= ERB.new(File.read(js_path), nil, nil, "_js").result(binding) %>
|
16
16
|
// ]]>
|
17
17
|
</script>
|
18
18
|
</head>
|
19
19
|
<body onload="pageLoaded()">
|
20
|
-
<%= ERB.new(File.read(template_path + "/selector.html.erb"),
|
20
|
+
<%= ERB.new(File.read(template_path + "/selector.html.erb"), nil, nil, "_select").result(binding) %>
|
21
21
|
<div class="inspec-report">
|
22
22
|
<h1><%= Inspec::Dist::PRODUCT_NAME %> Report</h1>
|
23
23
|
<% run_data.profiles.each do |profile| %>
|
24
|
-
<%= ERB.new(File.read(template_path + "/profile.html.erb"),
|
24
|
+
<%= ERB.new(File.read(template_path + "/profile.html.erb"), nil, nil, "_prof").result(binding) %>
|
25
25
|
<% end %>
|
26
26
|
|
27
27
|
<div class="inspec-summary">
|
28
28
|
<table id="platform" class="info">
|
29
|
+
<caption>Platform Information</caption>
|
29
30
|
<tr><th colspan=2><h4 id="platform-label">Platform Information</h4></th></tr>
|
30
31
|
<tr class= "name"><th>Name:</th><td><%= run_data.platform.name %></td></tr>
|
31
32
|
<tr class= "release"><th>Release:</th><td><%= run_data.platform.release %></td></tr>
|
32
33
|
<tr class= "target"><th>Target:</th><td><%= run_data.platform.target %></td></tr>
|
33
34
|
</table>
|
34
35
|
<table id="statistics" class="info">
|
36
|
+
<caption>Control Statistics</caption>
|
35
37
|
<tr><th colspan="2"><h4 id="statistics-label">Control Statistics</h4></th></tr>
|
36
38
|
<tr class= "passed"><th>Passed:</th><td><%= run_data.statistics.controls.passed.total %></td></tr>
|
37
39
|
<tr class= "skipped"><th>Skipped:</th><td><%= run_data.statistics.controls.skipped.total %></td></tr>
|
@@ -26,6 +26,7 @@
|
|
26
26
|
|
27
27
|
<h3 class="control-title">Control <code><%= control.id %></code></h3>
|
28
28
|
<table class="control-metadata info" id="control-metadata-<%= slugged_id %>">
|
29
|
+
<caption>Control Table</caption>
|
29
30
|
<tr class="status status-<%= status %>"><th>Status:</th><td><div><%= status.capitalize %></div></td></tr>
|
30
31
|
<% if control.title %><tr class="title"><th>Title:</th><td><%= control.title %></td></tr> <% end %>
|
31
32
|
<% if control.desc %><tr class="desc"><th>Description:</th><td><%= control.desc %></td></tr> <% end %>
|
@@ -35,6 +36,8 @@
|
|
35
36
|
<th>Tags:</th>
|
36
37
|
<td>
|
37
38
|
<table class="tags">
|
39
|
+
<caption>Tag Table</caption>
|
40
|
+
<tr><th>Tag Name</th><th>Tag Text</th></tr>
|
38
41
|
<% control.tags.each do |tag_name, tag_text| %>
|
39
42
|
<tr><td><%= tag_name %></td><td><%= tag_text %></td></tr>
|
40
43
|
<% end %>
|
@@ -71,7 +74,7 @@
|
|
71
74
|
</table>
|
72
75
|
|
73
76
|
<% control.results.each do |result| %>
|
74
|
-
<%= ERB.new(File.read(template_path + "/result.html.erb"),
|
77
|
+
<%= ERB.new(File.read(template_path + "/result.html.erb"), nil, nil, "_rslt").result(binding) %>
|
75
78
|
<% end %>
|
76
79
|
|
77
80
|
</div>
|
@@ -3,6 +3,7 @@
|
|
3
3
|
<h2 class="profile_title">Profile <%= display_name %> (<%= profile.name %>)</h2>
|
4
4
|
|
5
5
|
<table class="profile-metadata info" id="profile-metadata-<%= profile.name %>">
|
6
|
+
<caption>Profile Information Table</caption>
|
6
7
|
<tr class="profile-version"><th>Version:</th><td><%= profile.version %></td></tr>
|
7
8
|
<% if profile.summary %>
|
8
9
|
<tr class="profile-summary"><th>Summary:</th><td><%= profile.summary %></td></tr>
|
@@ -17,7 +18,7 @@
|
|
17
18
|
|
18
19
|
<% if profile.status == "loaded" %>
|
19
20
|
<% profile.controls.each do |control| %>
|
20
|
-
<%= ERB.new(File.read(template_path + "/control.html.erb"),
|
21
|
+
<%= ERB.new(File.read(template_path + "/control.html.erb"), nil, nil, "_ctl").result(binding) %>
|
21
22
|
<% end %>
|
22
23
|
<% end %>
|
23
24
|
</div>
|
@@ -2,6 +2,7 @@
|
|
2
2
|
<div class="result" id="result-<%= slugged_id %>">
|
3
3
|
<h4 class="resource-title">Resource <code><%= result.resource_title.to_s %></code></h4>
|
4
4
|
<table class="result-metadata info">
|
5
|
+
<caption>Result Information Table</caption>
|
5
6
|
<tr class="expectation_message"><th>Test:</th><td><code><%= result.expectation_message %></code></td></tr>
|
6
7
|
<tr class="status status-<%= result.status %>"><th>Status:</th><td><div><%= result.status.capitalize %></div></td></tr>
|
7
8
|
<% if result.status == "failed" %>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
# StreamingReporterProgressBar Plugin
|
2
|
+
|
3
|
+
## What This Plugin Does
|
4
|
+
|
5
|
+
This plugin is a streaming reporter plugin which shows the real-time progress of a running InSpec profile using a progress bar. It also outputs the ID of a running control with an indicator showing if the control has passed, failed or skipped.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "inspec-streaming-reporter-progress-bar/version"
|
2
|
+
|
3
|
+
module InspecPlugins
|
4
|
+
module StreamingReporterProgressBar
|
5
|
+
class Plugin < ::Inspec.plugin(2)
|
6
|
+
plugin_name :"inspec-streaming-reporter-progress-bar"
|
7
|
+
streaming_reporter :"progress-bar" do
|
8
|
+
require "inspec-streaming-reporter-progress-bar/streaming_reporter"
|
9
|
+
InspecPlugins::StreamingReporterProgressBar::StreamingReporter
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|